【问题标题】:Finding duplicate chars in argv[]在 argv[] 中查找重复字符
【发布时间】:2014-05-29 02:17:29
【问题描述】:

我正在尝试扫描我的参数列表 argv[],并确定是否有重复的字符。我已经尝试了一些东西,但似乎没有任何效果。我真的是 C 的新手,所以请忍受我可怕的代码:

char unavailableLetters[26] = "";
int pos = 0;
for(i = 0; i < (argc-1); i++) {
    int size = strlen(argv[i+1]);
    for(j = 0; j < size; j++) {
        char c = argv[i+1][j];

        if(j == 0) {
            unavailableLetters[pos] = c;
            pos+=1;
            } else {

            char *s = strchr (unavailableLetters, c);
            if(s == NULL) {
                unavailableLetters[pos] = c;
                pos += 1;
            }
        }
    }
}

我这里的逻辑是解析所有参数,然后解析每个字符,首先检查它是否包含在 availableLetters 数组中,如果不是 - 添加它,然后继续。但无论我尝试什么,它们要么全部被添加,要么一个都不添加。这可能不是最好的方法,但我没有想法。

  1. 列表项

【问题讨论】:

  • “重复字符”是什么意思?假设参数是"open hello",应该打印什么?
  • 谢谢,我确实得到了解决方案。但在这种情况下,输出应该是:o e l

标签: c arrays compare argv strchr


【解决方案1】:

这是一个我只简单测试过的解决方案。它仅适用于小写字母,并利用字母的 ascii 值是连续的这一事实(ascii a 为 97,这就是为什么我在分配索引时减去 97 并在打印出字母时将其加回)

#include <iostream>
using namespace std;

int main (int argc, char *argv[])
{
    int letters[26];

    for (int i = 0; i < 26; i++) {
        letters[i] = 0;
    }

    for (int i = 1; i < argc; i++) {
        cout << "processing word: " << argv[i] << endl;
        char *word = argv[i];
        for (int j = 0; j < strlen(word); j++) {
           cout << "\tprocessing letter: " << word[j] << endl;
           letters[(int)word[j]-97]++;
        }
    }

    cout << "Letters that appear only once: " << endl;
    for (int i = 0; i < 26; i++) {
        if (letters[i] == 1)
            cout << (char) (i+97) << endl;
    }

    return 0;
}

【讨论】:

    【解决方案2】:

    我在 C++ 上写了这个。这更像是一个伪代码,而不是一个示例。这仅适用于带有小写字母的参数。

    您的想法不错,但这也可以。 尝试维护一个数组,如果在前面的参数中找到字母,则存储在位置 i 中。之后,您可以使用 double for 遍历所有字母。

    如果当您点击一个字母时,数组上的值设置为 1,那么您之前已经看到该字母并且存在重复的字母。否则将数组上的字母位置设置为 1。

    如果 double for 完全通过,则参数中会重复任何字母。

    花点时间思考一下。这是代码

    char unavalible_chars[26] = ""; // This is the array of ocurrences it only works with the small letters
    
        int i;
        for (i = 0; i < argc; i++)
        {
            char* c = argv[i];
    
            while ((char)*c) {
    
                int cPos = (*c) - 97; // Modifiy a little this for all letters
    
                if (unavalible_chars[cPos]){
    
                    // Exist repeated
                    return 0;
                }
                else
                {
                    // Mark as present
                    unavalible_chars[cPos] = 1;
                }
            }
        }
    
        return 1;
    

    【讨论】:

      【解决方案3】:

      这是另一种方法。它为每个字符使用一个计数器,然后将显示多次出现的所有字符:

      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include <ctype.h>
      
      int main(int argC, char *argV[])
         {
         int arg;
         char *cp;  
         int counters[256];
      
         /* Set all counters to zero. */
         memset(counters, 0, sizeof(counters));
      
         /* Iterate through each character of each argV */
         for(arg=1; arg<argC; ++arg)  // Change to "for(arg=0;..." to include argV[0]
            for(cp=argV[arg]; *cp; ++cp)
               ++counters[(int)*cp];  //Change to "++counters[toupper(*cp)];" to ignore case.
      
         /* Print characters that occurred more than once. */ 
         printf("Duplicate character list: ");   
         for(arg=0; arg<256; ++arg)
            if(counters[arg] > 1)
               printf("%c ", arg);
      
         printf("\n");   
      
         return 0;
         }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-09-26
        • 2014-05-09
        • 2018-08-27
        • 1970-01-01
        • 2016-05-11
        • 2023-04-04
        相关资源
        最近更新 更多