将固定大小的数组更改为向量

时间:2017-07-09 18:31:51

标签: c++ arrays for-loop vector calculated-columns

给定文件包含对。然后取一个两位数的数字(称为X),并计算赢/输金额。赢/输规则是输入数字与X匹配,然后是胜利,获胜总数是(金额* 70);否则,它是(-amount)的损失。

  

For example: [ticket.txt] 09 10 13 15 25 21

如果折腾数为09,则票数的赢/输金额为(10 * 70 - 15 - 21 = 664)

如果投票数为42,则票数的赢/输金额为(-10 - 15 - 21 = -46)。

虽然按数组读取文件的大小是固定的。我的意思是,如果文件ticket.txt没有特定的大小,该怎么办?有人可以帮助我将数组的读取文件更改为vector或其他没有固定大小的文件。

  

For example: [ticket.txt] 09 10 13 15 25 21 .. ..

#include <iostream>
#include <fstream>

using namespace std;
int line1[100]; // array that can hold 100 numbers for 1st column
int line2[100]; // array that can hold 100 numbers for 2nd column
int main()
{
    int winNum, winAmount = 0, lostAmount = 0, result = 0;
    int num = 0; // num start at 0
    ifstream inFile; 
    inFile.open("Ticket.txt"); //open File
    if (inFile.fail())
    {
        cout << "Fail to open the file" << endl;      
        return 1;
    }


    int myArray[3][2];
    for(int i = 0; i < 3; i++)
        for(int j = 0; j < 2; j++)
            inFile >> myArray[i][j];

    cout << "Numbers from File: " << endl;

    for(int i = 0; i < 3; i++)
    {
        for(int j = 0; j < 2; j++)   
        {
            cout << myArray[i][j] << " ";
        }
        cout << "\n";       
    }

    cout << endl;
    cout << "Enter the toss-up number: "; // enter the win number
    cin >> winNum;

    for(int i = 0; i< 3;i++)
    {
        if (myArray[i][0] == winNum) 
        {
            winAmount = myArray[i][1] * 70; //  number user choose = win number, winAmount = winAmount * 70 - lostAmount
        }
        else
        {
            lostAmount = lostAmount + myArray[i][1]; //number user choose != win number, the amount will be -lost amounts
        }
    }

    result = winAmount - lostAmount;
    cout << result;

    cout << endl << endl;
    system("pause");
    return 0;
    }

1 个答案:

答案 0 :(得分:0)

有许多不同的方法可以解决这个问题。

可以制作vector vector

std::vector<std::vector<int>> myArray;

但这非常浪费。只有内部维度的大小可变,因此快速改进

std::vector<std::array<int, 2>> myArray;

加载myArray可能非常简单,具体取决于您要包含多少验证。这是最小的验证:

int number,amount;
while (inFile >> number >> amount)
{
    myArray.push_back({number,amount});
}

这将循环,直到无法读取两个int,无论是因为文件末尾还是文件中的垃圾。它也容易被具有磨损列数的文件所欺骗。更好的方法是使用std::getline来获得整行,并确保两行有效数字,而且每一行都没有其他内容。

其余代码未更改。

但是可能有更好的方法来做到这一点,考虑

a)损失金额永远不会改变。您可以预先计算它并在丢失时消除循环。

b)在此基础上,您可以在胜利中消除部分循环。损失金额包含中奖号码使用损失金额减去中奖金额。换句话说,

winnings = amount * 70 - (loss - amount)

相同
winnings = amount * 70 - loss + amount

winnings = amount * 71 - loss

所以我们可以在找到胜利后立即停止查看,只进行一次计算。

c)我们可以消除对std::map的查找循环的需要。

将文件读入std::map是类似的:

std::map<int, int> myMap;

int number,amount;
int loss = 0;
while (inFile >> number >> amount)
{
    myMap[number] = amount; // map the amount to the number
    loss += amount;
}

和查找类似

int result = 0;
auto found = myMap.find(winNum); // look in the map for a number

if (found != myMap.end()) // number is in the map
{
    result = 71* found->second; // take the winnings plus one extra to counterbalance 
                                // number's addition to the losses 
}
result -= loss; //remove the loss

完全消除了计算循环,更少的代码几乎总是更好。没有错误的代码没有错误。除非它不在那里是一个错误,但这是一个不同的问题。

注意:对于小文件,此方法将为SLOWER。 std::map比复制std::vector的时间复杂度低得多,但它必须执行的每次迭代都要贵得多。

Documentation on std::array

Documentation on std::vector

Documentation on std::map