仅读取文件C中的奇偶行

仅读取文件C中的奇偶行,c,file,random,C,File,Random,任务是从txt文件中读取一些随机行(奇数或偶数,我会指定),用户只需写入完全相同的行,如果正确(相同),程序将打印成功。问题是我不知道如何只读取奇数或偶数行,它也应该随机生成(比如奇数或偶数)。谢谢循环并忽略偶数项的常用方法是 for( int i = 0; thing = get_thing(); i++ ) { /* It's even, skip it */ if( abs(i % 2) == 0 ) continue; ...do stuff w

任务是从txt文件中读取一些随机行(奇数或偶数,我会指定),用户只需写入完全相同的行,如果正确(相同),程序将打印成功。问题是我不知道如何只读取奇数或偶数行,它也应该随机生成(比如奇数或偶数)。谢谢

循环并忽略偶数项的常用方法是

for( int i = 0; thing = get_thing(); i++ ) {
    /* It's even, skip it */
    if( abs(i % 2) == 0 )
        continue;

    ...do stuff with thing...
}
abs(i%2)==0检查偶数,
abs(i%2)==1检查奇数。如果要选择一个或另一个,请使用
int parity
abs(i%2)=parity


有效地从文件中选择一个随机行只需要少量的数学运算。您必须读取该文件一次,否则无法知道行的开始和结束位置

一个低效的算法将读取所有N行,然后选择一行,这可能会消耗大量内存。一个更有效的算法将只存储每行的起始位置。两者都是O(n)内存(意味着内存使用量随着文件大小的增长而增长)。但是有一个O(1)内存算法,它只需要存储一行

每行有1/N的机会被选中。高效的算法在读取每一行时将其应用于该行,但N是迄今为止读取的行数。在伪代码中

int num_lines = 0;
char *picked_line = NULL;
while( line = getline() ) {
    num_lines++;

    if( roll(num_lines) == num_lines ) {
        picked_line = line;
    }
}
因此,第一行有1/1的几率被选中。第二行有1/2的几率被选中。第三个有1/3的机会,依此类推

为什么这意味着每条线都有1/N的几率?好吧,让我们从三行中选择第一行

  • 一线队有1/1的机会。
    • 它被摘下来了。一线队的总赔率现在是1
  • 二线有1/2的机会。
    • 第一条线,被选中的一条,有1/2的存活几率
    • 一线队被选中的几率现在是1*1/2或1/2
  • 第三线有1/3的机会。
    • 第一条线,被选中的一条,有2/3的存活几率
    • 一线队被选中的几率现在是1*1/2*2/3或2/6或1/3

  • 您可以对第2行和第3行执行相同的操作,以向自己证明这是有效的。

    AFAIK您不能以非顺序方式读取文件。此外,没有办法知道一条线有多长。所以只需阅读所有行,如果行是偶数/奇数,则进行处理,否则丢弃所有行。所有行大小都相同吗?显示您尝试过的内容。行大小不同,单词可以有不同的长度…好的,谢谢,有没有办法读取随机行号?我的意思是,我不会处理整个文件,只处理那个特定的文件line@qwerty_不,如果不读取前面的n-1行,就无法到达第n行。@qwerty_uuu不,因为如果不读取整个文件,就无法知道行的开始和结束位置。但是,有一种方法可以做到这一点,而不必保存整个文件,只需读取一次。如果这是你想要的,请更新你的帖子。基本思想是每一行被选中的概率是
    1/num\u lines\u read
    。所以第一行是1/1,第二行是1/2,第三行是1/3。。。您阅读了文件,并对每一行进行了检查。@qwerty_uu我已经用基本算法更新了答案,从一行中选择了一个随机数。请更新您的问题以明确这是您想要的。注意:
    i%2==1
    仅检查正奇数。在OP的情况下,不应遇到负值
    i