2015-12-12 36 views
-1

我想写一个函数来检查一个字符串是否只有大写字母,并且字符串中的每个字母都有相同的数量。即AXXA是一个有效的字符串,但是AXX不是。删除[]弄乱了我的程序。发生了什么?

我的checkUpper函数工作正常。但是我的checkLetters函数只会在我的程序运行时第一次运行。

当我在函数返回前摆脱了delete []之后,它会一直工作。但我知道这会造成内存泄漏。

我只想问是什么原因导致它只能第一次工作?以及在删除删除[]后每次如何工作?

任何帮助将不胜感激。非常感谢你。

#include <iostream> 
#include <string> 
#include <ctype.h> 

using namespace std;enter code here 
string input; 
int NumOfLetters; 

//check if everything is uppercase; 
bool checkUpper(string input){ 
    for(int i=0;i<input.length();i++) 
     if(!isupper(input[i])) return false; 
    return true; 
} 

//check to see if there are the same number of runners for each team; 
bool checkLetters(string input){ 
    char* Letters= new char[input.length()];//worst case, all letters are used once; 
    NumOfLetters=0; //letter counter 
    for(int i=0; i<input.length();i++){ 
     if(Letters[NumOfLetters]!=input[i]){ 
      Letters[NumOfLetters]=input[i]; //putting different letters in Letters 
      NumOfLetters++; 
     } 
    } 

    int *CountLetters= new int[NumOfLetters]; //used to count each letter 

    for(int i=0; i<NumOfLetters;i++){ 
     for(int j=0;j<input.length();j++) 
      if(Letters[i]==input[j])CountLetters[i]++; //counting each letter 
    } 

    for(int i=0; i<NumOfLetters;i++){ 
     if(CountLetters[i]!=CountLetters[0]){ //comparing number of each letters to the first one; 
      delete[] Letters; 
      delete[] CountLetters; 
      return false; 
     } 
    } 
    delete[] Letters; 
    delete[] CountLetters; 
    return true; 
} 


int main(){ 
    while(true){ 
     cout<<"Enter a string of uppercase characters to indicate places(enter done to terminate):"; 
     cin>>input; 
     if(input=="done") break; 
     if(!checkUpper(input)){ 
      cout<<"Uppercase letters ONLY! try again.\n"; 
      continue; 
     } 
     if(!checkLetters(input)){ 
      cout<<"Each team must have the same number of runners! try again.\n"; 
      continue; 
     } 

     //to be filled; 

    } 
    return 0; 
} 
+2

你的代码是非常难读由于穷人格式。另外,为什么你使用'string'作为字符串数据,'new char []'?对所有字符串数据使用'std :: string'。 – PaulMcKenzie

+2

由于缺少标签格式,您的代码难以阅读。但是好像你的'Letters'和'CountLetters'数组都是从未初始化的,这意味着这个程序的工作机会很小。关于你的崩溃,'delete []'很少是原因 - 原因通常是先前的代码写在数组的边界之外并破坏内存。 –

+0

您发布的代码甚至不会调用'checkLetters()'。给出你在'checkLetters()'中出现问题的陈述,这是一个正面信号,表明你发布的代码与展示你的问题的代码不同。由于'delete'的问题通常是由于其他代码的错误行为(例如指针骚扰覆盖'new'和'delete'在内部使用的数据结构),所以没有人能够帮助您 - 找到代码中的问题是公平的看到大多数人的能力超出。 – Peter

回答

1

我不能看一眼看出问题,但一些评论:

  • 不要写一个裸体newdelete。在非常更糟糕的是,使用std::make_unique或类似的。但是,对于此应用程序std::stringstd::vector会更好。
  • 正如评论中指出的那样,您并未将CountOfLetters的内容初始化为零(new不适合您)。
  • checkLetters(其中初始化为Letters)的第一个循环需要是双循环。 (你没有检查那封信以前从未见过 - 只是它不是一个未初始化的值!)
  • 你应该更喜欢传递字符串作为const引用。

最后,checkLetters将使用std::map好得多:

bool checkLetters(const std::string& input) { 
     if (input.length() == 0) 
      return true; // Just in case no characters at all. 
     std::map<char,int> counts; 
     for (const char c : input) { 
      // No point in running over the string twice. Do it in one go. 
      if (!std::upper(c)) return false; 
      // If there is an entry in the map, increment it. If not, 
      // create it (with value zero), and then increment. 
      counts[c]++; 
     } 
     // input[0] would blow up if the string is length zero and we hadn't checked above 
     const int target = counts[input[0]]; 
     for (const auto& keyvalue : counts) 
     { 
      const int value = keyvalue.second; 
      if (value != target) 
       return false; 
     } 
     return true; 
    } 
+0

谢谢,我会修改我的代码立即进行初始化。 –

1

编辑:我误读的问题是“在输入每个字母只能有一个数”。这里是我的新答案:

我浏览了你的代码并纠正了你的错误。我基本上重写了原始代码的一部分,并做了一个简单的checkLetters函数。根本不需要动态分配,除非特定的情况要求。

您所能做的只是维护一个map<char,int>,它存储输入中每个字母的计数。在通过输入进行交互之后,我们保留一个变量mustHaveCnt,这是每个字母必须具有的计数。现在,遍历地图中的所有字母,如果计数超过mustHaveCnt变量,则返回false。否则,答案是正确的。

此外,我已改写您的条件输入。当输入为“done”时,它会正确终止。

#include <iostream> 
#include <string> 
#include <ctype.h> 
#include <map> 

using namespace std; 

//check if everything is uppercase; 
bool checkUpper(string input){ 
    for(int i=0;i<input.length();i++) 
     if(!isupper(input[i])) return false; 
    return true; 
} 

//Checks if the input has the same number of runners 
//use must have the header file 'map' included, e.i write "#include <map>" at the top 
bool checkLetters(string input){ 
    map<char,int> storeCnt; 
    for(int i=0;i<input.size();i++) 
     storeCnt[input[i]]++; //Increment the count of each letter found 
    int mustHaveCnt=storeCnt.begin()->second; //The second entry stores the count 
    for(map<char,int>::iterator it= ++storeCnt.begin(); it!=storeCnt.end(); it++) //Iterate and check cnt 
     if(it->second != mustHaveCnt) 
      return false; //terminate here since the count does not match 
    return true; 
} 

int main(){ 
    cout<<"Enter a string of uppercase characters to indicate places(enter done to terminate):\n"; 
    string input; //Let's avoid global declaration, unless needed 
    cin>>input; 
    while(input.compare("done")!=0) 
    { 
     int flag=1; 
     if(!checkUpper(input)){ 
      cout<<"Uppercase letters ONLY! try again.\n"; 
      flag=0; 
     } 
     if(flag && !checkLetters(input)){ 
      cout<<"Each team must have the same number of runners! try again.\n"; 
      flag=0; 
     } 
     if(flag) 
      cout<<"Valid String!\n"; 
     cin>>input; 
    } 
    return 0; 
} 
+0

我压低了你的答案,因为C++标准不能保证大写字母是连续的 - 事实上它们不是。首先,在使用EBCDIC的IBM大型机上,'Z' - 'A'远大于25。其次,根据默认的语言环境,像'Ü'这样的字母很可能会从'isupper'返回'true'并且全局数组?真?它不是线程安全的,没有理由不把它变成本地的。 –

+0

你到底在说什么?我使用ASCII代码约定并查看问题,他似乎没有使用IBM大型机或任何东西。 EBCDIC。你在开玩笑吗? C++标准?我指的是ASCII约定 – bholagabbar

+0

另外,线程安全吗?一个26 * 4字节的整数数组将导致严重问题。 yuhoo:/ – bholagabbar

相关问题