2015-11-04 36 views
0

我需要創建一個程序,其中1到100之間的隨機數放置在3D數組的每個維中。這些數組的大小各不相同,因此在執行時只遇到崩潰。用一維數組進行小規模嘗試,並使其正常工作。似乎不能大規模翻譯。我的代碼到目前爲止...需要在三維數組中插入1-100的隨機數

int const STOCK_AMOUNT = 1000, DAY_AMOUNT = 366, TIME_AMOUNT = 480; 
int randomGenerator(); 
void randomInsert(int array0[DAY_AMOUNT][TIME_AMOUNT][STOCK_AMOUNT]); 

int main() 
{ 
    int cube[DAY_AMOUNT][TIME_AMOUNT][STOCK_AMOUNT]; 
    srand((unsigned)time(0)); 
    randomInsert(cube); 
    return 0; 
} 

void randomInsert(int array0[DAY_AMOUNT][TIME_AMOUNT][STOCK_AMOUNT]) 
{ 
    for (int count1 = 0; count1 < DAY_AMOUNT; count1++) 
    { 
     for (int count2 = 0; count2 < TIME_AMOUNT; count2++) 
     { 
      for (int count3 = 0; count3 < STOCK_AMOUNT; count3++) 
      { 
       int randomGenerator(); 
       array0[count1][count2][count3] = randomGenerator(); 
       cout << endl; 
      } 
     } 
    } 
} 

int randomGenerator() 
{ 
    int randNum; 
    int lowerLimit = 1; 
    int upperLimit = 100; 
    randNum = (rand() % upperLimit) + lowerLimit; 
    return randNum; 
} 
+0

你的內部循環可能不需要cout語句。 (366,000 * 480換行!)而且,當你在這裏時,請描述你認爲運行程序的輸出應該是什麼? –

+0

同樣在內部循環中,您不需要轉發聲明randomGenerator()函數,該函數已在代碼頂部完成 –

+0

,因此在閱讀某些註釋和進一步詢問professor.stock_amount = 100後數組太大了day_amount = 50 time_amount = 8。基本上是一個olap立方體[Stock_amount] [day_amount] [time_amount] – SCSUjer

回答

3

您似乎超過堆棧大小。你的數組,在堆棧上創建,擁有大約175M整數,即大約700MB的內存。您需要設置編譯選項以增加堆棧大小。編輯:另外,請注意,將如此巨大的數組放在堆棧上通常被認爲是不好的做法。理想情況下,使用STL向量,這是處理數組的現代方法。

+1

增加堆棧大小通常不是一個好的解決方案。 – bames53

+0

@ bames53是真的,但這是另一場辯論。當然,STL會是一個更「現代」的方法,它會將數組移到堆中,但這個答案是對所提供代碼的特定評估。我將這句話添加到了考慮你的評論的答案中。 :) –

1

下面是使用STL的一個更復雜的版本:

#include <cassert> 
#include <cstddef> 
#include <cstdint> 
#include <ctime> 
#include <functional> 
#include <iostream> 
#include <random> 

using std::cout; 
using std::endl; 

// The size of a type that can hold values from 1 to 100. Used for storage. (Copy to int for calculation.) 
using elem_t = int_least8_t; 
// Lower and upper bounds: 
constexpr int lb = 1; 
constexpr int ub = 100; 

constexpr size_t stocks = 100, days = 300, times = 400; 
using pricearray_t = elem_t[days][times][stocks]; 

pricearray_t& init_prices() 
/* Returns a heap-allocated array that must be deleted with delete[]. */ 
{ 
    // This ugly little cast is brought to us by the C++ rules for array types. 
    pricearray_t &to_return = *(pricearray_t*) new pricearray_t; 
    const std::default_random_engine::result_type seed = std::time(NULL) * CLOCKS_PER_SEC + std::clock(); 
    std::default_random_engine generator(seed); 
    std::uniform_int_distribution<int_fast8_t> distribution(lb, ub); 

    auto x = std::bind(distribution, generator); 

    for (size_t i = 0; i < days; ++i) 
    for (size_t j = 0; j < times; ++j) 
     for (size_t k = 0; k < stocks; ++k) 
     to_return[i][j][k] = static_cast<elem_t>(x()); 

    return to_return; 
} 

int main(void) 
{ 
    const pricearray_t &prices = init_prices(); 

    long long int sum = 0; 
    for (size_t i = 0; i < days; ++i) 
    for (size_t j = 0; j < times; ++j) 
     for (size_t k = 0; k < stocks; ++k) { 
     const int x = prices[i][j][k]; 
     assert(x >= lb); 
     assert(x <= ub); 
     sum += x; 
     } 

    cout << "The mean is " << static_cast<double>(sum)/days/times/stocks << "." << endl; 

    delete[] &prices; 
    return EXIT_SUCCESS; 
} 

下面是一個使用智能指針來自動管理存儲一個版本:

#include <cassert> 
#include <cstddef> 
#include <cstdint> 
#include <ctime> 
#include <functional> 
#include <iostream> 
#include <memory> 
#include <random> 

using std::cout; 
using std::endl; 

// The size of a type that can hold values from 1 to 100. Used for storage. (Copy to int for calculation.) 
using elem_t = int_least8_t; 
// Lower and upper bounds: 
constexpr int lb = 1; 
constexpr int ub = 100; 

constexpr size_t stocks = 100, days = 300, times = 400; 
// The unique_ptr type doesn’t play nicely with arrays of known size. 
using pricearray_t = elem_t[][times][stocks]; 

std::unique_ptr<pricearray_t> init_prices() 
/* Returns a managed pointer to an array of uniformly-distributed values. 
*/ 
{ 
    // This smart pointer will use its move constructor to avoid copying the entire array. 
    std::unique_ptr<pricearray_t> to_return = std::make_unique<pricearray_t>(days); 
    const std::default_random_engine::result_type seed = std::time(NULL) * CLOCKS_PER_SEC + std::clock(); 
    std::default_random_engine generator(seed); 
    std::uniform_int_distribution<int_fast8_t> distribution(lb, ub); 
    auto x = std::bind(distribution, generator); 

    for (size_t i = 0; i < days; ++i) 
    for (size_t j = 0; j < times; ++j) 
     for (size_t k = 0; k < stocks; ++k) 
     to_return[i][j][k] = static_cast<elem_t>(x()); 

    return to_return; 
} 

int main(void) 
{ 
/* The contents of the smart pointer will be deleted automatically when it goes out of scope. 
    */ 
    const std::unique_ptr<pricearray_t> prices = init_prices(); 

    long long int sum = 0; 
    for (size_t i = 0; i < days; ++i) 
    for (size_t j = 0; j < times; ++j) 
     for (size_t k = 0; k < stocks; ++k) { 
     const int x = prices[i][j][k]; 
     assert(x >= lb); 
     assert(x <= ub); 
     sum += x; 
     } 

    cout << "The mean is " << static_cast<double>(sum)/days/times/stocks << "." << endl; 

    return EXIT_SUCCESS; 
} 
+0

這是如何有效地使用C++ 11及以後的一個很好的例子。 +1! – Cebtenzzre

+0

@ZirconiumHacker謝謝。我添加了一個使用智能指針的版本。 – Davislor

0

看來規格由提供的原始立方教授顯然太大了......奇怪教授怎麼會不明白這一點?縮減規格,現在有一些工作。主要股票應該爲每隻股票(100)找到股票價格的平均值(50)。

#include<iostream> 
#include<ctime> 
#include <cstdlib> 
#include <fstream> 
using namespace std; 
const int STOCK_AMOUNT = 100, DAY_AMOUNT = 50, TIME_AMOUNT = 8; 
int randomGenerator(); 
void priceGenerator(int [STOCK_AMOUNT][DAY_AMOUNT][TIME_AMOUNT]); 


int main() 
{ 
ofstream outputFile; 
int cube[STOCK_AMOUNT][DAY_AMOUNT][TIME_AMOUNT]; 
double total; 
srand((unsigned)time(0)); 
priceGenerator(cube); 
outputFile.open("Average_Day_Price"); 
for (int row = 0; row < STOCK_AMOUNT; row++) 
{ 
total=0; 
for (int col = 0; col < DAY_AMOUNT; col++) 
{  
for (int layer = 0; layer < TIME_AMOUNT; layer++) 
{   
total = cube[row][col][layer]; 
double average = (total/TIME_AMOUNT); 
outputFile << "STOCK Id:" << (row+1) << "--" << "--" << average <<endl:    
} 
} 
} 
outputFile.close(); 
return 0; 
} 
void priceGenerator(int array0[STOCK_AMOUNT][DAY_AMOUNT][TIME_AMOUNT]) 
{ 
int i,y, z; 
for (i = 0; i < STOCK_AMOUNT; i++) 
{ 
for (y = 0; y < DAY_AMOUNT; y++) 
{ 
for (z = 0; z < TIME_AMOUNT; z++)  
{ 
int randNum; 
int lowerLimit = 1; 
int upperLimit = 100; 
randNum = (rand() % upperLimit) + lowerLimit; 
array0[i][y][z] = randNum;   
} 
} 
} 
}