2016-10-11 12 views
1

我有一個包含單詞列表的文本文件。在C++中以非ASCII格式的第一個字母對字符串的向量排序

我用ifstream讀這段話成爲一個vector,現在我想他們在類似的順序進行排序:

A a B b C c [...] 

我想這使用第三for循環泡沫搜索內實現算法看每個單詞的第一個字符(我知道這是遠離最有效的方式,特別是如果我使用大型數據集)

然後檢查字母和下一個字母是大寫還是小寫,如果大寫字母與當前字母是相同的字母,則切換,但是似乎沒有工作。

void bubble_Sort (vector <string> & words) 
{ 
    for (unsigned i = words.size(); i >= 2; --i) 
    { 
    for (unsigned k = 0; k + 1 < i; k++) 
    { 
     int hi = k+1; 
     string temp1 = words[hi]; 
     string temp2 = words[k]; 
     int smallsize = words[hi].size(); 
     int smallprecedence = 0; 

     if (words[k].size() < words[hi].size()) 
     smallsize = words[k].size(); 

     for (unsigned j = 0; j < smallsize; j++) 
     { 
     if (temp1[j] >= 'A' && temp1[j] <= 'Z') 
     { 
      if (temp2[j] >='a' && temp2[j] <= 'z') 
      { 
      char lowercase1 = temp1[j] + 32; 
      if (lowercase1 == temp2[j]) 
      { 
       string temp = words[k]; 
       words[k] = words[hi]; 
       words[hi] = temp; 
       break; 
      } 
      } 

      else if (temp2[j] >= 'A' && temp2[j] <= 'Z') 
      { 
      if (temp1[j] < temp2[j]) 
      { 
       string temp = words[k]; 
       words[k] = words[hi]; 
       words[hi] = temp; 
       break; 
      } 
      } 
     } 

     if (temp1[j] >= 'a' && temp1[j] <= 'z') 
     { 
      if (temp2[j] >= 'A' && temp2[j] <= 'Z') 
      { 
      char uppercase1 = temp1[j] - 32; 
      if (uppercase1 < temp2[j]) 
      { 
       string temp = words[k]; 
       words[k] = words[hi]; 
       words[hi] = temp; 
       break; 
      } 
      } 

      else if (temp2[j] >= 'a' && temp2[j] <= 'z') 
      { 
      if (temp1[j] < temp2[j]) 
      { 
       string temp = words[k]; 
       words[k] = words[hi]; 
       words[hi] = temp; 
       break; 
      } 
      } 
     } 

     else if (temp1[j] == temp2[j] && temp1.size() < temp2.size()) 
      ++smallprecedence; 
     } 

     if (smallprecedence == smallsize) 
     { 
     string temporary = words[k]; 
     words[k] = words[hi]; 
     words[hi] = temporary; 
     } 
    } 
    } 
} 
+1

你是否正在實施自己的bubblesort作爲練習?如果沒有,你應該使用'std :: sort'並實現比較函數。 –

+0

是的,我正在嘗試使用冒泡排序來排序向量的順序A和B b等等,儘管在ASCII比A更大,這是我一直存在的問題。 –

回答

0

可以使用std::sort排序矢量,採用std::string::at()得到一個std::string的第一個字符的引用:

std::vector<std::string> vec; 
// 
std::sort(vec.begin(), vec.end(), [](const std::string& lhs, const std::string& rhs) 
{ 
    char l_ch, r_ch; 
    l_ch = lhs.at(0); 
    r_ch = rhs.at(0); 
    return l_ch < r_ch; 
}); 
+0

在使用'at()'之前更好地檢查空字符串。 –

+0

@FrerichRaabe:對,只是提供了一個片段,甚至沒有經過測試的代碼。 std :: compare可能用於比較,但OP堅持第一個字母 – seccpur

3

不要推倒重來。只需修改默認的比較函數即可aA < bB(無論大小寫)和A < a。

編輯我使用了錯誤的比較功能。它應該返回true<false>=。此問題已修復

std::vector<std::string> vec; 
// 
std::sort(vec.begin(), vec.end(), [](const std::string& lhs, const std::string& rhs) 
{ 
    const char* s1=lhs.c_str(); 
    const char* s2=rhs.c_str(); 
    while(true) { 
    // first ignore case 
    if (std::toupper(*s1) < std::toupper(*s2)) return true; 
    if (std::toupper(*s1) > std::toupper(*s2)) return false; 
    // end of both strings, exact match 
    if (*s1 == 0 && *s2 == 0) return false; 
    // compare upper case vs lower case ('A' vs 'a') 
    if (*s1 > *s2) return false; 
    if (*s1 < *s2) return true; 
    ++s1; ++s2; 
    } 
}); 
0

我認爲這是真的夠跳過正好等於前綴,然後用uppercasing比較一次:

std::vector<std::string> vec; 
// 
std::sort(vec.begin(), vec.end(), [](const std::string& lhs, const std::string& rhs) 
{ 
    const char* s1=lhs.c_str(); 
    const char* s2=rhs.c_str(); 
    while(*s1 && *s1 == *s2) {++s1; ++s2;} 
    int rc = toupper(*s1) - toupper(*s2); 
    if (rc) return rc; 
    return *s1 - *s2; 
}); 

如果您需要按首字母只比較,只需刪除while(*s1 && *s1 == *s2) {++s1; ++s2;}

1

首先,擺脫硬編碼的ASCII-ISMS。 C和C++長期以來具有確定字符是字母,數字,大寫字母,小寫字母等的功能。查看它們。

其次,描述明確什麼進入確定的順序,你希望得到的結果是英寸

第三,從這樣的描述,編寫一個函數採用兩個字符串,並告訴您是否第一串應該在第二串之前出現。使用,其功能在排序。

相關問題