2016-10-08 7 views
1

ベクトルの数字を置換しようとしています。置換を行ったときのベクトルのエラー

以下は私のコードです。このコードは非常に簡単です。第1に、ベクトルの入力サイズはユーザ入力によって決定される。そして、すべての数値を1つの文字列に連結したときに、最大整数値と最小整数値を見つけるために、ベクトル内のすべての数値が置換されます。

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

using namespace std; 

string retS(const vector<int>& v) 
{ 
    string s = ""; 
    for (int e : v) { 
     s += to_string(e); 
    } 
    return s; 
} 


int main(void) { 
    int num = 0; 

    cin >> num; 

    vector<int> numbers; 

    for (int i = 0; i < num; ++i) { 
     int n; 
     cin >> n; 
     numbers.push_back(n); 
    } 

    sort(numbers.begin(), numbers.end()); 

    unsigned long long maxVal = 0; 
    unsigned long long minVal = 987654321; 
    do { 
     string s = retS(numbers); 
     if (stoll(s) > maxVal) { 
      maxVal = stoi(s); 
     } 


     if (stoll(s) < minVal) 
      minVal = stoi(s); 

    } while (std::next_permutation(numbers.begin(), numbers.end())); 

    cout << maxVal+minVal << endl; 
} 

ただし、2桁の数字を入力したときにエラーが発生するという問題があります。たとえば、10 20 30 40 50 60 70 80 90 20を私のベクトルに入力したところ、私のコードは機能しませんでした。私は1つまたは2つの数字だけが受け入れられると仮定した場合、連結された文字列は20(〜20まで)のサイズになる可能性があるため、整数変数の範囲にあると思います。 したがって、整数変数をunsigned long longの型に変更しました。これはintです。これは整数型を格納するための最長範囲の値ですが、実行時にプログラムが中止されました。

このコードはうまく動作するように手伝ってもらえますか?

+0

期待される出力は何ですか? – Zereges

+0

予想される出力は、すべての置換された数値の最大値+最小値になり、連結されます。 – sclee1

+0

@Anders K. expected出力は入力値に依存します。たとえば1,2,3を入力すると、maxValは '321'、minValは' 123'になります。問題は2桁の値の場合です。 – sclee1

答えて

2

Zeregesが指摘したように、ここでの問題は、C++に組み込まれている最大の数値型の容量を超える数値を格納しようとしていることです。そのような長い数字を文字列として格納するこの問題を解決できます。これにより問題は解決しますが、コードが少し遅くなります。

文字列で必要以上に戦いたくない場合は、これが役に立ちます:https://mattmccutchen.net/bigint/大きな整数で作業するライブラリです。

希望します。

2

申し訳ありませんが、私は私の投稿に誤りを犯しました。

---間違いの初め---あなたが期待するよう

はまず、文の下におそらく機能しない場合があります。

sort(numbers.begin(), numbers.end()); 

thisによれば、ソート()は昇順に[最初、最後)の範囲内の要素をソートします。実際、std::next_permutation()についても同じ問題があります。

実際にはかっこと角括弧の違いがあります。 [は、>=を意味し、)は、<を意味する。あなたのコードによれば、最後の要素はソートされません。

---間違いの終わり---私はちょうどend()は、ベクトルコンテナ内の最後の要素を参照する反復子を返していないことを発見した

、過去- -end要素は、ベクトルの最後の要素に続く理論的要素です。

さらに、値を保持するために2つのunsigned long longが宣言されています。

unsigned long long maxVal = 0; 
unsigned long long minVal = 987654321; 

987654321はあなたが保存したい値の上限であると思われます。しかし、あなたのコードには潜在的な問題はなく、値の上限が失われる可能性があります。

(1)maxValには上限が適用されません。

if (stoll(s) > maxVal) { //may add a upper boundary for maxVal 
    maxVal = stoi(s); 
} 

(2)stoll()及びstoi()の機能は、それぞれlong longintを返します。上限値であるlong longおよびintより大きい数値がキャッチされた場合、上記の2つの関数はstd::out_of_range例外をスローします。これは、関数の使用上の制限です。これはあなたが遭遇したランタイムエラーであるようです。また、値を格納するためにunsigned long longを宣言しようとしましたが、2つの関数を使用する際の制限は解除されません。

修正するには、Carlosからの提案を試してみてください。

以下は、Carlosからの提案の実装です。

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

using namespace std; 

string retS(const vector<int>& v) 
{ 
    string s = ""; 
    for (int i = 0; i < v.size(); i++) { 
     s += to_string(v.at(i)); 
    } 
    return s; 
} 

//prone to error 
bool str1GreaterThanStr2(const string str1, const string str2) 
{ 
    if (str1.size() != str2.size()) 
     return (str1.size() > str2.size()); 

    int cursor = 0; 
    while (cursor < str1.size()) 
    { 
     if (str1.at(cursor) != str2.at(cursor)) 
      return (str1.at(cursor) > str2.at(cursor)); 
     cursor++; 
    } 

    return false; //if both string are the same 
} 

int main(void) { 
    int num; 
    vector<int> numbers; 

    cin >> num; 
    for (int i = 0; i < num; ++i) { 
     int n; 
     cin >> n; 
     numbers.push_back(n); 
    } 

    sort(numbers.begin(), numbers.end()); 

    string maxStr = retS(numbers); 
    string minStr = retS(numbers); 

    while (std::next_permutation(numbers.begin(), numbers.end())) 
    { 
     string str = retS(numbers); 
     maxStr = str1GreaterThanStr2(str, maxStr) ? str : maxStr; 
     minStr = str1GreaterThanStr2(str, minStr) ? minStr : str; 
    } 

    cout << maxStr << endl; 
    cout << minStr << endl; 
} 


/* 
test case tried: 
10 
10 20 30 40 50 60 70 80 90 20 
*/ 

これが役立ちます。

関連する問題