2016-11-29 65 views
2

我必须从一个.txt文件中读取并使用不同的.txt文件进行读取。我必须使用插入排序,以便根据两个数字对它们进行排序。我只能得到这一点,我不知道如何在这个程序中做插入排序,我有两个数字来排序。从txt文件中进行C++插入排序

这里是我的代码:

#include <iostream> 
#include <fstream> 
#include <string> 

using namespace std; 

int main(void) 
{ 
    int serialno[100], suratno[100], ayatno[100]; 
    string order; 

    string str; 
    char ch; 
    int i = 0; 
    int j, temp; 

    ifstream fin; 
    fin.open("text.txt"); 

    if(!fin) 
    { 
     cout << "Cannot open file \'text.txt\'! Quitting.\n"; 
     exit(0); 
    } 

    while(fin) 
    { 

     fin.get(ch); //gets . 

     getline(fin, order, '('); //allegedly it removes the delimiter char from stream too 

     fin >> suratno; 
     fin.get(ch); //gets : 
     fin >> ayatno; 
     fin.get(ch); //gets) 
     fin.get(ch); //gets \n 

     cout << serialno << "." << order << "("<<suratno<<":<<ayatno<<")\n"; 
    } 

    fin.close(); 

    //sort algorithm    
    for (int i = 0; i < length; i++){ 
     j = i; 

     while (j > 0 && suratno [j] < suratno [j-1]){ 
       temp = suratno [j]; 
       suratno [j] = suratno [j-1]; 
       suratno [j-1] = temp; 
       j--; 
       cout << serialno << endl; 
       } 
     } 
    } 

    ofstream fout; 
    fout.open("newtext.txt"); 

    if(!fout) 
    { 
     cout << "Cannot open output file\'orderedquranorders.txt\'!Quitting.\n"; 
     exit(0); 
    } 

    i = 0; 
    //write sorted list to output file 

    fout.close(); 

    cout << i << " orders successfully sorted and written.\n"; 
} 

这是文本文件(应采用支架数量,先用冒号之前数,其次用冒号后的数字):

1. Do not be rude in speech (3:159) 
2. Restrain Anger (3:134) 
3. Be good to others (4:36) 
4. Do not be arrogant (7:13) 
5. Forgive others for their mistakes (7:199) 
6. Speak to people mildly (20:44) 
7. Lower your voice (31:19) 
8. Do not ridicule others (49:11) 
9. Be dutiful to parents(17:23) 

电流输出:

  1. 不要在语音粗鲁(3:159)
  2. 眕(3:134)
  3. 要对别人好(4:36)
  4. 要孝顺父母(17:23)

预期输出:

  1. 眕( 3:134)
  2. 不要在言语粗鲁(3:159)
  3. 要对别人好(4:36)
  4. 要孝顺父母(17:23)

在数量和序列号两方面进行排序保持不变

+0

去阅读帮助中心的“如何提出一个很好的问题。”另请阅读Eric Lippert的[如何调试小程序](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)。你目前有一个巨大的主要功能。至少将其分为三个功能:读取输入,对数据进行排序,写入输出。然后,您可以在开始测试排序之前测试“读取输入”和“写入输出”。 –

+0

@MartinBonner我有一个txt文件我必须阅读,它需要排序。 (3:159)“这些数字在括号内” 2.抑制愤怒(3:134) 3.对别人好(4:36) –

+0

@YSC有什么建议吗? –

回答

0

为了比较两个数字对,你可以进行比较,如:

if(suratno[i] < suratno[i-1] || (suratno[i] == suratno[i-1] && ayatno[i] < ayatno[i-1])){ 
    /* swap */ 
} 

或者你可以使用一个表达式:expr = suratno * 10000 + ayatno。并只有一个比较:

if(expr[i] < expr[i-1]){ 
    /* swap */ 
} 

而且,我对你的算法/代码的一些意见:

  • 不要使用using namespace std。特别是在大型程序中,因为它可能会导致不明确的错误(请参阅示例here)。如果您想避免std::,请改用using std::<name>。防爆。 using std::string。一般来说,请避免using namespace xxxx
  • 我看到你手动解析了输入行,我更喜欢使用正则表达式,它的功能更强大,功能更强大,但需要一点学习。
  • 当需要写入错误消息时,总是使用C++写入标准错误码流cerr
  • 在排序算法中,最好从1开始比0更好,因为第一个项目没有以前的项目进行比较。
  • 最后,交换可以用一个存在的C++函数完成。

这里是你的代码重新组织,并使用正则表达式,我试图解释尽可能:

#include <iostream> 
#include <fstream> 
#include <string> 
#include <regex> 
#include <vector> 
#include <algorithm> 

using std::string; 

struct Line { 
    int expr; // Expression used to compare 
    string text; // Original line without initial number 
}; 

int main() { 
    std::regex linePattern(
     "\\d+"  // 1 or more digits 
     "\\. "  // '. ' (dot followed by 1 space) 
     "("   // begin char group #1 
      ".*"  // zero or more chars 
      "\\(" // '(' (left parenthesis) 
      "(\\d+)" // char group #2 (suratno: 1+ digits) 
      ":"  // ':' (colon) 
      "(\\d+)" // char group #3 (ayatno: 1+ digits) 
      "\\)" // ')' (right parenthesis) 
     ")"   // end char group #1 
    ); 
    std::smatch groups;   // Regular expression found char groups 
    std::vector<Line> lines; // Vector to store the readed lines 

    // Read lines parsing content 
    std::ifstream fin("text.txt"); 
    if(!fin){ 
     std::cerr << "Cannot open file 'text.txt'! Quitting.\n"; 
     return 1; 
    } 
    string line; 
    while (std::getline(fin, line)) 
     if (std::regex_search(line, groups, linePattern) && groups.size() > 0) { 
      int suratno = std::stoi(groups[2]); 
      int ayatno = std::stoi(groups[3]); 
      int compExpr = suratno * 10000 + ayatno; // assumes ayatno < 10,000 
      lines.push_back({ compExpr, groups[1] }); 
     } 
    fin.close(); 

    // sort algorithm (better start in 1) 
    for (size_t i = 1; i < lines.size(); i++) 
     for (size_t j = i; j > 0 && lines[j].expr < lines[j - 1].expr; j--) 
      std::swap(lines[j], lines[j - 1]); 

    std::ofstream fout("newtext.txt"); 
    if(!fout){ 
     std::cerr << "Cannot open output file 'orderedquranorders.txt'! Quitting.\n"; 
     return 1; 
    } 
    for (size_t i = 0; i < lines.size(); i++) 
     fout << i + 1 << ". " << lines[i].text << std::endl; 
    fout.close(); 

    std::cout << lines.size() << " orders successfully sorted and written.\n"; 
    return 0; 
} 

注:正则表达式实在是一个字符串"\\d+\\. (.*\\((\\d+):(\\d+)\\))",我使用了C/C++功能在编译之前连接由空格分隔的字符串,因此编译器只能看到一个字符串。

不要忘记用-std=c++11选项编译。

0

using namespace std;被认为是不好的做法,有时可能会很危险。检查this

这里是您的解决方案:

#include <iostream> 
#include <fstream> 
#include <string> 

int main() 
{ 
    int suratno[100], ayatno[100]; 
    std::string order[100]; 

    char ch; 
    int count = 0; 
    int tempInt; 
    std::string tempStr; 

    std::ifstream fin; 
    fin.open("text.txt"); 

    if (!fin) 
    { 
     std::cout << "Cannot open file \'text.txt\'! Quitting.\n"; 
     exit(0); 
    } 
    else 
    { 
     while (fin) 
     { 
      fin.get(ch); //gets the numbers 
      fin.get(ch); //gets . 

      getline(fin, order[count], '('); //allegedly it removes the delimiter char from stream too 

      fin >> suratno[count]; 
      fin.get(ch); //gets : 
      fin >> ayatno[count]; 
      fin.get(ch); //gets) 
      fin.get(ch); //gets \n 

      std::cout << count + 1 << "." << order[count] << "(" << suratno[count] << ":" << ayatno[count] << ")\n"; 
      count++; 
     } 
    } 
    fin.close(); 
    std::cout << std::endl; 

    // sort algorithm (we must sort two times) 
    for (int i = 0; i < count; i++) 
    { 
     for (int j = i; j > 0 && suratno[j] < suratno[j - 1]; j--) 
     { 
      tempInt = suratno[j]; 
      suratno[j] = suratno[j - 1]; 
      suratno[j - 1] = tempInt; 

      tempInt = ayatno[j]; 
      ayatno[j] = ayatno[j - 1]; 
      ayatno[j - 1] = tempInt; 

      tempStr = order[j]; 
      order[j] = order[j - 1]; 
      order[j - 1] = tempStr; 
     } 
    } 

    for (int i = 0; i < count; i++) 
    { 
     for (int j = i; j > 0 && suratno[j] == suratno[j - 1] && ayatno[j] < ayatno[j - 1]; j--) 
     { 
      tempInt = ayatno[j]; 
      ayatno[j] = ayatno[j - 1]; 
      ayatno[j - 1] = tempInt; 

      tempInt = suratno[j]; 
      suratno[j] = suratno[j - 1]; 
      suratno[j - 1] = tempInt; 

      tempStr = order[j]; 
      order[j] = order[j - 1]; 
      order[j - 1] = tempStr; 
     }  
    } 

    // print the sorted list just to check 
    for (int i = 0; i < count; i++) 
    { 
     std::cout << i + 1 << "." << order[i] << "(" << suratno[i] << ":" << ayatno[i] << ")\n"; 
    } 

    // write sorted list to output file 
    std::ofstream fout; 
    fout.open("newtext.txt"); 

    if (!fout) 
    { 
     std::cout << "Cannot open output file\'orderedquranorders.txt\'!Quitting.\n"; 
     exit(0); 
    } 
    else 
    { 
     for (int i = 0; i < count; i++) 
     { 
      fout << i + 1 << "." << order[i] << "(" << suratno[i] << ":" << ayatno[i] << ")\n"; 
     } 
    } 
    fout.close(); 

    std::cout << std::endl; 
    std::cout << count << " orders successfully sorted and written.\n"; 

    return 0; 
}