K& R练习1-9(C)

时间:2010-07-22 04:14:21

标签: c

  

“编写程序将其输入复制到   它的输出,替换每一串   一个空白就有一个或多个空白。“

我假设他的意思是输入类似......

  

我们(空白)(空白)(空白)的(空白)的(空白)(空白)(空白)(空白)的商场!

...并输出如下:

  

我们(空白)的(空白)的(空白)的(空白)的商场!

这可能比我要做的更容易,但是,我似乎无法弄明白。我真的不想要代码...更多伪代码

另外,我该如何看待这个?我很确定我编写的任何程序至少需要一个variable,一个while循环,几个if语句,并且将同时使用getchar()putchar()功能......但除此之外,我不知所措。我还没有真正的程序员思路,所以如果你能给我一些建议,我应该如何看待一般的“问题”,那就太棒了。

(请不要提起else,我现在还没有那么远,所以我的范围已经超出了我的范围。)

29 个答案:

答案 0 :(得分:22)

将程序看作是在迭代输入时在不同状态之间移动的机器。

一次读取输入的一个字符。如果它看到除空白之外的任何内容,它只会打印它看到的字符。如果它看到空白,则转换到不同的状态。在该状态下,它打印一个空白,然后不会打印空白,如果它看到它们。然后,它继续读取输入,但忽略它看到的所有空白 - 直到它击中一个非空白的字符,此时它会切换回第一个状态。

(顺便说一句,这个概念被称为有限状态机,许多理论计算机科学工作已经进入他们能做什么和不能做什么。Wikipedia可以告诉你更多,虽然可能比你正在寻找的更复杂的细节。;))

答案 1 :(得分:12)

伪代码

while c = getchar:
    if c is blank:
        c = getchar until c is not blank
        print blank
    print c

C

如果您愿意,可以在此处替换使用isblank。没有说明哪些字符设计为空白,或者用什么空白值代替其他字符打印。

在Matthew在下面的评论中提出了许多观点后,这个版本和包含isblank的版本是相同的。

int c;
while ((c = getchar()) != EOF) {
    if (c == ' ') {
        while ((c = getchar()) == ' ');
        putchar(' ');
        if (c == EOF) break;
    }
    putchar(c);
}

答案 2 :(得分:5)

由于C中的关系运算符产生整数值1或0(如本书前面所述),逻辑表达式“当前字符非空白或前一个字符非空白”可以使用整数运算进行模拟,从而缩短(如果有点神秘)代码:

int c, p = EOF;
while ((c = getchar()) != EOF) {
    if ((c != ' ') + (p != ' ') > 0) putchar(c);
    p = c;
}

变量p初始化为EOF,以便在第一次比较时它具有有效的非空值。

答案 3 :(得分:4)

这就是我得到的:

while ch = getchar()
   if ch != ' '
      putchar(ch)
   if ch == ' '
      if last_seen_ch != ch
         putchar(ch)
   last_seen_ch = ch

答案 4 :(得分:1)

许多其他人已经在其代码中使用了最后一个字符逻辑,但以下版本可能更易于阅读:

int c, prevchar;
while ((c = getchar()) != EOF) {
    if (!(c == ' ' && prevchar == ' ')) {
        putchar(c);
        prevchar = c;
    }
}

答案 5 :(得分:1)

首先将两个变量character和last_character声明为整数。当你没有到达文件的末尾时(while(character = getchar()!= EOF)执行此操作; 1.如果是字符!=''那么       打印字符       last_character =字符 2.如果字符==''      如果last_character ==''      最后一个字符=字符    否则打印字符

答案 6 :(得分:1)

以下是我对伪练习的练习算法的看法:

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

答案 7 :(得分:1)

使用不使用else或and运算符的约束。此代码仅在空白变量等于1时才打印空白,并且重置计数器的唯一方法是通过键入除空白之外的其他内容。希望这会有所帮助:

包括

/ *编写一个程序,用单个空格替换空格* /

void main(){     int c,bl;

bl = 0;

while((c = getchar()) != EOF){
    if(c == ' '){
        ++bl;
        if(bl == 1){
            putchar(' ');
        }
    }
    if(c != ' '){
        putchar(c);
        bl = 0;
    }
}       

}

答案 8 :(得分:1)

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

答案 9 :(得分:1)

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

答案 10 :(得分:1)

#include <stdio.h>
int main()
{
    int c;
    while( (c = getchar( )) != EOF )
    {           
        if (c == ' ') 
        {
            while ((c = getchar()) == ' ');
            putchar(' ');
            putchar(c);
        }
        else 
            putchar(c);
    }
    return 0;
}

答案 11 :(得分:1)

我写了这篇文章并且似乎正在发挥作用。

 # include <stdio.h>
 int main ()
{

int c,lastc;
lastc=0;
while ((c=getchar()) != EOF)
    if (((c==' ')+ (lastc==' '))<2)
        putchar(c), lastc=c;
 }

答案 12 :(得分:0)

解决方案1:根据k&R书中涵盖的主题:

#include <stdio.h>

int main()
{
    int c;

while ((c = getchar()) != EOF)
    {
       if  (c == ' ') 
       {while ( getchar() == ' ' )
        ;  // ... we take no action
        }

        putchar(c);

    }

return 0;
}

解决方案2:使用程序状态:

int main()
{
    int c, nblanks = 0 ;

while ((c = getchar()) != EOF)  
{
   if (c != ' ')
       { putchar(c);
         nblanks = 0;}

   else if (c==' ' && nblanks == 0) // change of state
            {putchar(c);
             nblanks++;}
}
return 0;
}

解决方案3:基于最后一次看到的字符

int main()
{
int c, lastc = 0;

while ((c = getchar()) != EOF)
    {
        if ( c != ' ')
        {putchar(c);}


        if (c == ' ')
        {
            if (c==lastc)
                ;
            else putchar(c);

        }

        lastc = c;
    }

return 0;
}

答案 13 :(得分:0)

考虑到问题,我还确保程序在各种标签,空格以及将它们组合在一起以形成各种组合的情况下都能流畅运行! 这是我的代码,

add_filter( 'woocommerce_add_to_cart_fragments', 'iconic_cart_count_fragments', 10, 1 );
function iconic_cart_count_fragments( $fragments ) {

    $fragments['.fa-shopping-cart'] = '<i class="fa fa-shopping-cart" class="header-cart-count">' . "<span class='cart-indicator'>" . WC()->cart->get_cart_contents_count() . '</span>'. '</i>';
    return $fragments; 

    $cart_count = WC()->cart->get_cart_contents_count();
    if ( $cart_count !== 0 ) {
    // Here's where I want to Hide .cart-indicator
    }
}

使用空格和制表符的各种组合随意运行所有测试用例。

答案 14 :(得分:0)

我刚开始写这本书,这里是我用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;
}

答案 15 :(得分:0)

/*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;
}

答案 16 :(得分:0)

#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;

}

我希望这会有所帮助。

答案 17 :(得分:0)

这是仅使用目前在K&R's C中描述的技术的解决方案。除了使用变量来实现finite state change以区分第一个空格和连续的空格之外,我还添加了一个变量来计算空格以及一个print语句以验证总数。这有助于我更好地围绕getchar()putchar() - 以及main()中while循环的范围。

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

答案 18 :(得分:0)

这是我的回答,我目前和你几年前在同一个地方。

我只使用了书中所教授的语法,并且只在需要时将多个空格缩减为一个空格。

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

我删除了部分尚未介绍的中断部分,希望这有助于像我这样的新人:)

答案 19 :(得分:0)

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

答案 20 :(得分:0)

像许多其他人一样,我也在研究这本书,发现这个问题非常有趣。

我已经提出了一段代码,它只使用了之前已经解释过的内容(因为我没有咨询任何其他资源,只是在玩代码)。

有一个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; } } 来比较当前字符和前一个字符。 是否存在此代码不起作用的边缘情况?

{{1}}

答案 21 :(得分:0)

我也开始使用K&amp; R教科书,我想出了一个解决方案,该解决方案仅使用到目前为止所涵盖的材料。

工作原理:

首先,设置一些计数器空白&#39;为零。这用于计算空白。

如果找到空白,请增加计数器空白&#39;一个人。

如果找不到空白,则首先进行子测试:计数器是否为空白&#39;是等于还是大于1?如果是,那么首先打印一个空白,然后设置计数器空白&#39;回到零。

完成这个子测试后,回去和putchar一起找不到任何字符是空白的。

这个想法是,在放入一个非空白字符之前,首先要做一个测试,看看是否有一些空白被计算过。如果之前有空白,先打印一个空白,然后重置空白计数器。这样,对于下一轮空白,计数器再次为零。如果该行上的第一个字符不是空白,则计数器无法增加,因此不会打印空白。

一个警告,我还没有进入书中,所以我还不熟悉语法,所以{}括号可能写在不同的地方,但我的例子工作正常。

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

答案 22 :(得分:0)

要仅使用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;
    }
}

答案 23 :(得分:0)

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

答案 24 :(得分:0)

让新人们更容易接受这本书的方法 (通过不知道任何事情然后在K&amp; R中出现的第22页)。

致@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 */
  }
}

答案 25 :(得分:0)

#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 = ' ';
            }                   
        }   
    }
}

答案 26 :(得分:0)

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>

答案 27 :(得分:0)

我在书中的同一点。如果发现空白,我的解决方案就是计算++,如果找到空白以外的其他任何内容,则将计数重新归零。

对于if语句,我再另一个检查来检查count的值(如果为零),然后打印。

虽然在学习的这一点上,我不应该关注两种方法的效率,但哪种方法是有效的。)这里接受的解决方案同时在内部或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;
        }


    }
}

答案 28 :(得分:0)

#include <stdio.h>

main() {
    int input, last = EOF;
    while ((input = getchar()) != EOF) {
       if (input == ' ' && last == ' ') continue;
       last = input; 
       putchar(input);
    }
}