我想从[1,10]中多次绘制1个整数,然后检查每个整数出现的次数。我写了这段代码,它正在编译但显示分段错误。请问,请指出问题出在哪里?
#include <iostream>
#include <random>
#include <array>
int main(){
std::random_device rd;
std::mt19937 dre(rd());
std::uniform_int_distribution <int> di(1,10);
std::array<int,10> count{0};
for(int i=0;i<10000;++i)
{
int rand=di(dre);
count[rand]++;
}
for (int foo: count){
count[foo]/=10000;
std::cout << foo << " " << count[foo] << std::endl;
}
}
答案 0 :(得分:4)
如果你定义一个由10个元素组成的数组,就像你在这里一样:
std::array<int,10> count{0};
然后数组将具有索引0-9。因此count
的范围是count[0]
到count[9]
。
但是,这里:
count[rand]++;
当rand
为10时,您正在尝试访问不存在的count [10]
。
要在您的修改中回答后续问题,您需要循环并创建10000
随机数,此处:
for(int i=0;i<10000;++i)
{
int rand=di(dre);
当您在10个不同的数字之间拣选时,您希望每个数字的数量大约为1000,并且分布均匀。
但是,当您打印结果时,将每个计数除以10000:
count[foo]/=10000;
因此,这意味着每个计数现在大约为0.1。当你将它存储在一个int中时,它会向下舍入为零。
答案 1 :(得分:2)
您的统一分布应定义为:
std::uniform_int_distribution <int> di(0, 9);
因为您的数组元素已从0
索引到9
。原样,您的rand
变量最终将变得大于9
,此时您正在读取界限,从而导致undefined behavior。即使rand
保持在边界内,基于for
循环的范围也将显示UB,因为foo
存在实际数组元素的值,但仍用作索引。应该通过引用传递:
for (int& foo : count) {
foo /= 10000;
std::cout << foo << '\n';
}
此外,如果您使用的是C ++ 11,那么您需要在std::array初始化程序中使用双括号:
std::array<int, 10> count{ { 0 } };
答案 2 :(得分:2)
你调用count[rand]
,其中count有10个项目,意味着索引在0..9范围内,但是rand在1..10范围内,所以每隔一段时间它会调用{{1}这导致你的seg错误。
使分发使用[0..9]代替:count[10]
答案 3 :(得分:2)
使用 oExcel = CreateObject("Excel.Application")
oBook = oExcel.Workbooks.Add
oSheet = oBook.Worksheets(1)
oSheet.Range("B1").Value = "Test"
array1(i, 1) = 0
oSheet.Range("B1").NumberFormat = "0.00"
oSheet.Range("A2").Resize(i, 1).Value = array1
oBook.SaveAs("C:\New folder\excel\" & datenw & ".xlsx")
oBook.Close(True)
oExcel.Quit()
,for (int foo: count)
依次等于foo
中的每个元素。您需要在循环中使用count
而不是foo
,或者如果需要索引,则使用显式count[foo]
循环。
此外,for
是包含边界的,因此您需要使用std::uniform_int_distribution
而不是0, 9
对其进行初始化,以索引您的十个元素1, 10
。