此练习的其他逻辑缺失

时间:2015-05-06 19:40:48

标签: objective-c c delimiter word-count

编写基本程序来计算字符串中的单词数。我已更改原始代码以说明单词之间的多个空格。通过将一个变量设置为当前索引并将一个变量设置为前一个索引并进行比较,我可以说"如果此当前索引是一个空格,但前一个索引包含的不是空格(基本上是一个字符) ,然后增加字数"。

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

我尝试添加&#34;或&#34;用于说明&#34;;&#34;等分隔符的陈述&#34;&#34;和&#34;。&#34;而不只是看着一个空间。从逻辑上讲,我不知道我能做些什么来解释任何不是字母的东西(但最好只限于这四个分隔符 - 。,;和空格。

2 个答案:

答案 0 :(得分: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

以上只是原始算法的一步 - 用状态而不是前一个字符重新编写。

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

要测试角色是否属于特定类型,您有两个简单的选择:

  • 如果这只是一个练习,你很乐意坚持使用ASCII范围的字符,那么有isdigit()isletter()等功能。

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

请参阅上述两种选择的文档。

HTH

答案 1 :(得分:0)

我不明白,你应该能够添加或发表声明......

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

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