[アルゴリズム]プログラマファイル名のソート


このブログは、非商業的な学業のためにのみ投稿されています.

1.問題分析

  • ファイル名がHEAD-NMBER(int)順に昇順に並べられている問題.
  • TAILは関係なく、HEADもNUMBERも同じなら入力順で安定したソートが必要です.
  • 2.回答プロセス(挿入)

  • 元組を使ったことがありますが、熟練していないので、少し時間がかかりました.
  • 3.トラブルシューティング

  • 分析台に従って行います.
  • 4.コード

    #include <string>
    #include <vector>
    #include <tuple>
    #include <algorithm>
    #include <iostream>
    
    using namespace std;
    
    bool compare(tuple<string, string, int> fileA, tuple<string, string, int> fileB)
    {
        int numA, numB;
        string headA, headB;
        
        tie(ignore, headA, numA) = fileA;
        tie(ignore, headB, numB) = fileB;
        
        if(headA == headB)
        {
            if(numA == numB)
                return false;
            return numA < numB;
        }
        return headA < headB;
    }
    
    string lowerCase(string s)
    {
        for(int i = 0; i < s.length(); i++)
            if(s[i] >= 'A' && s[i] <= 'Z')
                s[i] += 32;
        return s;
    }
    
    int findNum(string filename, int pos)
    {
        for(int i = pos; i <= filename.length(); i++)
            if(filename[i] >= '0' && filename[i] <= '9')
                return i;
        return -1;
    }
    
    int findTail(string filename, int pos)
    {
        for(int i = pos; i <= filename.length(); i++)
            if(filename[i] > '9' || filename[i] < '0')
                return i;
        return -1;
    }
    
    vector<string> solution(vector<string> files) {
        int pos1 = 0, pos2 = 0;
        string filename = "";
        vector<string> answer;
        tuple<string, string, int> fileT;
        vector<tuple<string, string, int>> filesT;
        
        for(int i = 0; i < files.size(); i++)
        {
            filename = files[i];
            get<0>(fileT) = filename;
            filename = lowerCase(filename);
            pos1 = findNum(filename, 0);
            pos2 = findTail(filename, pos1 + 1);
            
            get<1>(fileT) = filename.substr(0, pos1);
            get<2>(fileT) = stoi(filename.substr(pos1, pos2 - pos1));
            
            filesT.push_back(fileT);
        }
        stable_sort(filesT.begin(), filesT.end(), compare);
        for(auto i : filesT)
            answer.push_back(get<0>(i));
        return answer;
    }

    5.学習の達人のコード

  • 関数をmakeLowerやfindNumIdxと命名するのには違いがあります.
  • また,
  • 変換というライブラリ関数を用いて,変換関数を一度に適用することも新たに知られている.
  • のソート方法から新しい方法を学びました.
  • 通常pairまたはtupleを用いて2つの変数を比較関数処理する.
  • まず
  • NUMBER(後順位)を安定順位付けし、HEAD(ライン順位)も安定順位付けして欲しい順位になりました.どちらが効率的か分かりません.
  • #include <iostream>
    #include <algorithm>
    #include <string>
    #include <vector>
    #include <cctype>
    using namespace std;
    char makeLower(char c)
    {
        if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
        return c;
    }
    int findNumIdx(const string &str)
    {
        int i;
        for (i = 0; i < str.length(); i++)
        {
            if (str[i] >= '0' && str[i] <= '9')
                break;
        }
        return i;
    }
    int getNumber(string str)
    {
        return std::stoi(str.substr( findNumIdx(str) ));
    }
    string getHeader(string str)
    {
        string rtn = str.substr(0, findNumIdx(str));
    
        std::transform(rtn.begin(), rtn.end(), rtn.begin(), makeLower);
    
        return rtn;
    }
    
    bool numComp(string str1, string str2) { return getNumber(str1) < getNumber(str2); }
    bool headComp(string str1, string str2) { return getHeader(str1).compare(getHeader(str2)) < 0; }
    
    vector<string> solution(vector<string> files)
    {   
        std::stable_sort(files.begin(), files.end(), numComp);
    
        std::stable_sort(files.begin(), files.end(), headComp);
    
        return files;
    }