K & R Упражнение 1-9 (C)
"Напишите программу для копирования ее ввода в его выход, заменяя каждую строку один или несколько заготовок одним пробелом.
Я предполагаю, что он подразумевает ввод чего-то вроде...
Мы (пробел) (пробел) (пробел) идти (пробел) до (пробел) (пробел) (пробел) далее (пробел) торговый центр!
... и вывести его так:
Мы (пробел) идти (пробел) до (пробел) клавиши (пробел) торговый центр!
Это, наверное, проще, чем я это делаю, но все же я не могу понять, как это понять. Я действительно не хочу, чтобы код... более псевдо-код.
Также, как я должен смотреть на это? Я уверен, что любая программа, которую я пишу, понадобится, по крайней мере, одному циклу variable
, while
, парам if
и будет использовать функции getchar()
и putchar()
... но кроме того, я в недоумении. Пока у меня пока еще нет программистов, поэтому, если бы вы могли дать мне несколько советов относительно того, как я должен смотреть на "проблемы" в целом, это было бы потрясающе.
(И, пожалуйста, не поднимайте else
, я так далеко не попал в книгу, так что из моего объема.)
Ответы
Ответ 1
Псевдокод
while c = getchar:
if c is blank:
c = getchar until c is not blank
print blank
print c
С
Здесь вы можете заменить isblank
здесь, если хотите. Неизвестно, какие символы убираются пустым или какое пустое значение должно быть напечатано вместо других.
После многих замечаний, сделанных Матфеем в комментариях ниже, эта версия и та, которая содержит isblank
, одинаковы.
int c;
while ((c = getchar()) != EOF) {
if (c == ' ') {
while ((c = getchar()) == ' ');
putchar(' ');
if (c == EOF) break;
}
putchar(c);
}
Ответ 2
Посмотрите на свою программу как машину, которая перемещается между различными состояниями, когда она итерации по входу.
Он считывает ввод одного символа за раз. Если он видит что-то другое, кроме пробела, он просто печатает символ, который он видит. Если он видит пробел, он переходит в другое состояние. В этом состоянии он печатает один пробел, а затем не печатает пробелы, если видит их. Затем он продолжает чтение ввода, но игнорирует все пробелы, которые он видит, - пока он не ударит по символу, который не является пустым, и в этот момент он переключается обратно в первое состояние.
(Это понятие, кстати, называется конечной автономией, и многие теоретические работы в области информатики вошли в то, что они могут и чего не могут сделать. Wikipedia может рассказать вам больше, хотя, возможно, более сложные детали, чем вы ищете.))
Ответ 3
Так как реляционные операторы в C производят целочисленные значения 1 или 0 (как объяснялось ранее в книге), логическое выражение "текущий символ не пустым или предыдущий символ не пустым" может быть смоделировано с целочисленной арифметикой, что приводит к сокращению ( если несколько загадочный) код:
int c, p = EOF;
while ((c = getchar()) != EOF) {
if ((c != ' ') + (p != ' ') > 0) putchar(c);
p = c;
}
Переменная p
инициализируется с помощью EOF
, так что она имеет действительное непустое значение во время самого первого сравнения.
Ответ 4
Вот что я получил:
while ch = getchar()
if ch != ' '
putchar(ch)
if ch == ' '
if last_seen_ch != ch
putchar(ch)
last_seen_ch = ch
Ответ 5
Я очень много работал над поиском решения, которое использовало только материал, который уже был рассмотрен в первой части первой главы книги. Вот мой результат:
#include <stdio.h>
/* Write a program to copy its input to its output, replacing each string of one or more blanks by a single blank. */
main()
{
int c;
while ((c = getchar()) != EOF){
if (c == ' '){
putchar(c);
while ((c = getchar()) == ' ')
;
}
if(c != ' ')
putchar(c);
}
}
Ответ 6
Я написал это и, кажется, работаю.
# include <stdio.h>
int main ()
{
int c,lastc;
lastc=0;
while ((c=getchar()) != EOF)
if (((c==' ')+ (lastc==' '))<2)
putchar(c), lastc=c;
}
Ответ 7
#include <stdio.h>
int main()
{
int c;
while( (c = getchar( )) != EOF )
{
if (c == ' ')
{
while ((c = getchar()) == ' ');
putchar(' ');
putchar(c);
}
else
putchar(c);
}
return 0;
}
Ответ 8
#include <stdio.h>
main()
{
int c, numBlank=0 ;
while((c= getchar())!=EOF)
{
if(c ==' ')
{
numBlank ++;
if(numBlank <2)
{
printf("character is:%c\n",c);
}
}
else
{
printf("character is:%c\n",c);
numBlank =0;
}
}
}
Ответ 9
То же объяснение с Matt Joiner, но этот код не использует break
.
int c;
while ((c = getchar()) != EOF)
{
if (c == ' ') /* find a blank */
{
putchar(' '); /* print the first blank */
while ((c = getchar()) == ' ') /* look for succeeding blanks then… */
; /* do nothing */
}
if (c != EOF) /* We might get an EOF from the inner while-loop above */
putchar(c);
}
Ответ 10
Сначала объявите два символа переменных и last_character как целые числа. Если вы не достигли конца файла (while (character = getchar()!= EOF) сделайте это;
1. Если символ!= '', Тогда печатный символ last_character = символ
2. Если символ == '' if last_character == '' последний символ = символ else print character
Ответ 11
Псевдокод:
Initialize character
Initialize consecutive_whitespace_counter
while it is not the end of the file:
if character is not blank:
print character
consecutive_whitespace_counter = 0
if character is blank:
if consecutive_whitespace_counter = 0:
print a blank
Increase consecutive_whitespace_counter
и вот фактический код в C:
int c; //character
int cws; //consecutive white spaces counter
while((c=getchar()) != EOF){
if(c!=' '){
putchar(c);
cws = 0;
}
if(c==' '){
if(cws == 0){
putchar(' ');
++cws;
}
}
}
ps: это ответ, который я написал во время работы над упражнениями в этой книге, я написал этот ответ, пытаясь не использовать какой-либо синтаксис, методы или функции, которые официально не были представлены на страницах книги до этого упражнения, поэтому я использовал только операторы if (нет других операторов), что также объясняет отсутствие каких-либо "break" -задавлений и в результате: почему решение немного многословно.
Ответ 12
Вот как я думаю об алгоритме этого упражнения, в псевдокоде:
define ch and bl (where bl is initially defined to be 0)
while ch is = to getchar() which is not = to end of file
do the following:
if ch is = to blank and bl is = 0
--> output ch and assign the value 1 to bl
else --> if ch is = to blank and bl is = 1
--> do nothing
else --> output ch and assign the value 0 to bl
Пример реализации в C:
#include <stdio.h>
#include <stdlib.h>
main() {
long ch,bl=0;
while ((ch=getchar()) != EOF)
{
if (ch == ' ' && bl == 0)
{
putchar(ch);
bl=1;
} else if (ch == ' ' && bl == 1) {
// no-op
} else {
putchar(ch);
bl=0;
}
}
return 0;
}
Ответ 13
#include <stdio.h>
main() {
int input, last = EOF;
while ((input = getchar()) != EOF) {
if (input == ' ' && last == ' ') continue;
last = input;
putchar(input);
}
}
Ответ 14
Я в том же пункте в книге. и мое решение идет с созданием count ++, если пустое найдено и возвращает счетчик к нулю, если не найдено ничего, кроме пустого.
Для оператора if я помещаю еще одну проверку, чтобы проверить значение count (если равно нулю) и затем распечатать.
Хотя на этом этапе обучения я не должен заботиться об эффективности двух методов, но какой из них эффективен.) Принятое решение здесь с while while while или b.), которое я предложил выше.
Мой код выглядит следующим образом:
#include <stdio.h>
main()
{
int count=0,c;
for( ; (c=getchar())!=EOF; )
{
if(c==' ')
{
if(count==0)
{
putchar(c);
count++;
}
}
if(c!=' ')
{
putchar(c);
count=0;
}
}
}
Ответ 15
1.Count the number of blanks.
2.Replace the counted number of blanks by a single one.
3.Print the characters one by one.
<code>
main()
{
int c, count;
count = 0;
while ((c = getchar()) != EOF)
{
if (c == ' ')
{
count++;
if (count > 1)
{
putchar ('\b');
putchar (' ');
}
else putchar (' ');
}
else
{
putchar (c);
count = 0;
}
}
return;
}
</code>
Ответ 16
#include <stdio.h>
main()
{
int CurrentChar, LastChar;
LastChar = '1';
while ((CurrentChar = getchar()) != EOF)
{
if (CurrentChar != ' ')
{
putchar(CurrentChar);
LastChar = '1';
}
else
{
if (LastChar != ' ')
{
putchar(CurrentChar);
LastChar = ' ';
}
}
}
}
Ответ 17
способ облегчить новые люди застряли в этой книге
(не зная ничего, кроме того, что было до 22-го уровня в K & R).
кредиты @Michael, @Mat и @Matthew, чтобы помочь мне понять
#include <stdio.h>
main()
{
int c;
while ((c = getchar()) != EOF) /* state of "an input is not EOF" (1) */
{
if (c == ' ') /* "blank has found" -> change the rule now */
{
while ((c = getchar ()) == ' '); /* as long you see blanks just print for it a blank until rule is broken (2) */
putchar(' ');
}
putchar(c); /* either state (2) was broken or in state (1) no blanks has been found */
}
}
Ответ 18
#include <stdio.h>
int main(void)
{
long c;
long nb = 0;
while((c = getchar()) != EOF) {
if(c == ' ' || c == '\t') {
++nb;
} else {
if(nb > 0) {
putchar(' ');
nb = 0;
}
putchar(c);
}
}
return 0;
}
Ответ 19
Чтобы сделать это, используя только циклы while и if, трюк заключается в том, чтобы добавить переменную, которая запоминает предыдущий символ.
Loop, reading one character at a time, until EOF:
If the current character IS NOT a space:
Output current character
If the current character IS a space:
If the previous character WAS NOT a space:
Output a space
Set previous character to current character
В коде C:
#include <stdio.h>
main()
{
int c, p;
p = EOF;
while ((c = getchar()) != EOF) {
if (c != ' ')
putchar(c);
if (c == ' ')
if (p != ' ')
putchar(' ');
p = c;
}
}
Ответ 20
Я также начинаю с учебника K & R, и я придумал решение, которое использует только материал, который был закрыт до этого момента.
Как это работает:
Во-первых, установите счетчик "пробелов" в ноль. Это используется для подсчета пробелов.
Если пробел найден, увеличьте счетчик "пробелы" на единицу.
Если пробел не найден, сначала выполните подтест: является ли счетчик "пробелами" равным или больше 1? Если да, то сначала напечатайте пробел и после этого установите счетчик "пробелы" обратно в ноль.
После выполнения этого подтеста вернитесь назад и putchar, какой бы символ не был признан пустым.
Идея заключается в том, что перед тем, как поместить непустой символ, сначала выполните тест, чтобы увидеть, если раньше были подсчитаны пробелы. Если раньше были пробелы, сначала распечатайте один пробел, а затем reset счетчик пробелов. Таким образом, счетчик снова равен нулю для следующего раунда пробелов. Если первый символ в строке не является пустым, счетчик не мог увеличиться, поэтому пустая строка не печатается.
Одно предупреждение, я не зашел очень далеко в книгу, поэтому я еще не знаком с синтаксисом, так что возможно, что скобки {} могут быть написаны в разных местах, но мой пример работает нормально.
#include <stdio.h>
/* Copy input to output, replacing each string of one or more blanks by a single blank. */
main()
{
int c, blanks;
blanks = 0;
while ((c = getchar()) != EOF) {
if (c != ' ') {
if (blanks >= 1)
printf(" ");
blanks = 0;
putchar(c); }
if (c == ' ')
++blanks;
}
}
Ответ 21
Как и многие другие люди, я изучаю эту книгу и нашел этот вопрос очень интересным.
Я придумал фрагмент кода, который использует только то, что было объяснено перед упражнением (поскольку я не консультируюсь с каким-либо другим ресурсом, а просто играю с кодом).
Существует цикл while
для анализа текста и один if
для сравнения текущего символа с предыдущим.
Есть ли случаи, когда этот код не работает?
#include <stdio.h>
main() {
// c current character
// pc previous character
int c, pc;
while ((c = getchar()) != EOF) {
// A truthy evaluation implies 1
// (learned from chapter 1, exercice 6)
// Avoid writing a space when
// - the previous character is a space (+1)
// AND
// - the current character is a space (+1)
// All the other combinations return an int < 2
if ((pc == ' ') + (pc == c) < 2) {
putchar(c);
}
// update previous character
pc = c;
}
}
Ответ 22
for(nb = 0; (c = getchar()) != EOF;)
{
if(c == ' ')
nb++;
if( nb == 0 || nb == 1 )
putchar(c);
if(c != ' ' && nb >1)
putchar(c);
if(c != ' ')
nb = 0;
}
Ответ 23
Вот мой ответ, я нахожусь в том же месте, что вы были лет назад.
Я использовал только синтаксис, который преподавался до этого момента в книгах, и он уменьшает количество пробелов в одном пространстве только по мере необходимости.
#include<stdio.h>
int main(){
int c
int blanks = 0; // spaces counter
while ((c = getchar()) != EOF) {
if (c == ' ') { // if the character is a blank
while((c = getchar()) == ' ') { //check the next char and count blanks
blanks++;
// if(c == EOF){
// break;
// }
}
if (blanks >= 0) { // comparing to zero to accommodate the single space case,
// otherwise ut removed the single space between chars
putchar(' '); // print single space in all cases
}
}
putchar(c); //print the next char and repeat
}
return 0;
}
Я удалил разрывную часть, поскольку она еще не была введена в книге, надеюсь, что эта помощь станет новой, как я:)
Ответ 24
Это решение, использующее только методы, описанные до сих пор в K & R C. В дополнение к использованию переменной для достижения конечного изменения состояния для выделения первого пробела из следующих пробелов я также добавил переменную для подсчета пробелов вместе с оператором печати для проверки общего числа. Это помогло мне немного обернуть голову вокруг getchar()
и putchar()
, а также область цикла while в main().
// Exercise 1-9. Write a program to copy its input to its output, replacing
// each string of one or more blanks by a single blank.
#include <stdio.h>
int main(void)
{
int blank_state;
int c;
int blank_count;
printf("Replace one or more blanks with a single blank.\n");
printf("Use ctrl+d to insert an EOF after typing ENTER.\n\n");
blank_state = 0;
blank_count = 0;
while ( (c = getchar()) != EOF )
{
if (c == ' ')
{
++blank_count;
if (blank_state == 0)
{
blank_state = 1;
putchar(c);
}
}
if (c != ' ')
{
blank_state = 0;
putchar(c);
}
}
printf("Total number of blanks: %d\n", blank_count);
return 0;
}
Ответ 25
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int c, flag=0;
while((c=getchar()) != EOF){
if(c == ' '){
if(flag == 0){
flag=1;
putchar(c);
}
}else{
flag=0;
putchar(c);
}
}
return 0;
}
Надеюсь, это поможет.
Ответ 26
/*a program that copies its input to its output, replacing each string of one or more blanks by a single blank*/
#include <stdio.h>
#include<stdlib.h>
int main(void)
{
double c;
char blank = ' ';
while((c = getchar()) != EOF)
{
if(c == ' ')
{
putchar(c);
while(( c = getchar() )== ' ')
{
if(c != ' ')
break;
}
}
if(c == '\t')
{
putchar(blank);
while((c = getchar()) == '\t')
{
if(c != '\t')
break;
}
}
putchar(c);
}
return 0;
}
Ответ 27
// K & R Exercise 1.9
// hoping to do this with as few lines as possible
int c = 0, lastchar = 0;
c = getchar();
while (c != EOF) {
if (lastchar != ' ' || c != ' ') putchar(c);
lastchar=c;
c=getchar();
}
Ответ 28
Я только начал книгу, и вот решение, которое я нашел, используя 3 оператора if, надеюсь, это достаточно ясно:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int c = 0, sp = 0; /* sp for spaces*/
while ((c = getchar()) != EOF){
if (c == ' ')
++sp; /* If character introduced was a space,
it starts to count them*/
if (c != ' ')
sp = 0; /* If character introduced wasn't a space,
then it resets counter to zero*/
if (sp < 2)
putchar(c); /*If there are less than 2 spaces,
then the character will be printed, otherwise
it won't (therefore it will always keep only 1 space)*/
}
return 0;
}
Ответ 29
Принимая во внимание то, что задано в вопросе, я также позаботился о том, чтобы программа работала гладко в случае различных вкладок, пробелов, а также в тех случаях, когда они объединяются в одну комбинацию! Вот мой код,
int c, flag = 1;
printf("Enter the character!\n");
while ((c = getchar()) != EOF) {
if (c == ' '||c == '\t') {
c=getchar();
while(c == ' '|| c == '\t')
{
c = getchar();
}
putchar(' ');
if (c == EOF) break;
}
putchar(c);
}
Не стесняйтесь запускать все тестовые наборы, используя различные комбинации пробелов и вкладок.