【问题标题】:additional logic to this exercise missing缺少此练习的其他逻辑
【发布时间】:2015-05-07 04:38:41
【问题描述】:

编写一个计算字符串中单词数的基本程序。我已经更改了原始代码以说明单词之间的多个空格。通过将一个变量设置为当前索引,将一个变量设置为前一个索引并比较它们,我可以说“如果当前索引是空格,但前一个索引包含空格以外的内容(基本上是说一个字符),那么增加字数”。

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        //establishing the string that we'll be parsing through.
        NSString * paragraph = @"This is a test paragraph and we will be testing out a string counter.";

        //we're setting our counter that tracks the # of words to 0
        int wordCount = 0;

        /*by setting current to a blank space ABOVE the for loop, when the if statement first runs, it's comparing [paragraph characterAtIndex:i to a blank space. Once the loop runs through for the first time, the next value that current will have is characterAtIndex:0, while the if statement in the FOR loop will hold a value of characterAtIndex:1*/

        char current = ' ';

        for (int i=0; i< paragraph.length; i++) {

            if ([paragraph characterAtIndex:i] == ' ' && (current != ' ')) {
                wordCount++;
            }
            current = [paragraph characterAtIndex:i];

        //after one iteration, current will be T and it will be comparing it to paragraph[1] which is h.

        }
        wordCount ++;
        NSLog(@"%i", wordCount);
    }
    return 0;
}

我尝试添加“或”语句来说明分隔符,例如“;” “,“ 和 ”。”而不是只看一个空间。它没有用......从逻辑上讲,我能做什么来解释不是字母的任何东西(但最好将它限制为这四个分隔符 - . , ; 和空格。

【问题讨论】:

  • 你考虑过没有任何分隔符的单个单词的边缘情况吗?
  • @hiandbaii 如果“段落”字符串只有一个没有分隔符的单词,我的代码运行良好。
  • 为什么不使用strtok,添加任意数量的分隔符,然后循环调用直到完成?

标签: objective-c c delimiter word-count


【解决方案1】:

解决这些类型问题的标准方法是构建一个有限状态机,您的代码不完全是一个,但它很接近。

不要考虑比较以前和当前的字符,而是考虑状态 - 你可以只从两个开始,在一个单词中不在一个单词中词

现在,对于每个状态,您都要考虑当前角色在动作和状态变化方面的含义。例如,如果状态是不在一个单词中,而当前字符是一个字母,那么操作是增加单词计数,下一个状态是在一个单词中.

在(Objective-)C 中,您可以使用enum 来构建一个简单的有限状态机,以在循环中提供状态名称和case 语句。在伪代码中是这样的:

typedef enum { NotInWord, InWord } State;

State currentState = NotInWord;
NSUInteger wordCount = 0;

for currentChar in sourceString
   case currentState of
      NotInWord:
         if currentChar is word start character -- e.g. a letter
         then
            increment wordCount;
            currentState = InWord;

      InWord:
         if currentChar is not a word character -- e.g. a letter
         then
            currentState = NotInWord;
   end case
end for

以上只是您原始算法的一个步骤 - 根据状态而不是前一个字符对其进行重铸。

现在,如果您想变得更聪明,可以添加更多状态。例如“卡兰的问题”有多少个单词?二。因此,您可能希望在一个单词中允许使用一个撇号。为了解决这个问题,您可以添加一个状态AfterApostrophe,其逻辑与当前InWord 相同;并修改InWord 逻辑以包括如果当前字符是撇号,则下一个状态是AfterApostrophe - 这将允许在一个单词中使用一个撇号(或其结尾,这也是有效的)。接下来您可能需要考虑连字符等...

要测试一个字符是否是特定类型,您有两个简单的选择:

  • 如果这只是一个练习,并且您乐于坚持使用 ASCII 字符范围,则可以使用 isdigit()isletter() 等函数。

  • 如果您想处理完整的 Unicode,您可以使用 NSCharacterSet 类型及其预定义的字母、数字等集合。

有关上述两种选择,请参阅文档。

HTH

【讨论】:

    【解决方案2】:

    没看懂,应该可以加or语句....

    int main(void) {
        char paragraph[] = "This is a test paragraph,EXTRAWORDHERE and we will be testing out a string.";
        char current = ' ';
        int i;
        int wordCount = 0;
    
    
        for (i = 0; i < sizeof(paragraph); i++){
            if ((paragraph[i] == 32 || paragraph[i] == 44) && !(current == 32 || current == 44)){ //32 = ascii for space, 44 for comma
                wordCount++;
            }
            current = paragraph[i];
        }
        wordCount++;
        printf("%d\n",wordCount);
    return 0;
    }
    

    我想最好将电流的比较从不等于更改为等于。希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-08
      相关资源
      最近更新 更多