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);
}

Не стесняйтесь запускать все тестовые наборы, используя различные комбинации пробелов и вкладок.