我这个约瑟夫环有点啥问题欸


#include
#include"sqlist.h"
using namespace std;
int main()
{
    int n, m, z = 0;
    cin >> n >> m;
    int* a = new int[n];
    for (int i = 1; i <= n; i++)
    {
        a[i - 1] = i;
    }
    SqList* l;
    CreateList(l, a, n);
    int j, y=1;
    int e = 0;
    while (!ListEmpty(l))
    {
        j = 1;
        for (j; j <= n; j++,y++)
        {
            if (y%m==0)
            {
                ListDelete(l, j, e);
                cout << e;
                y = 1;
                n--;
            }
        }
        n = n - n / m;
    }
    return 0;
}

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
这段代码的问题在于在循环中同时改变了循环变量 j 和链表的长度 n,导致出现了错误的删除操作,进而导致程序出错。

具体来说,当删除第 j 个元素后,下一个要删除的元素的下标应该是 j,但是由于此时已经改变了 n 的值,所以实际上下一个要删除的元素的下标应该是 j % n,而不是 j。此外,每当删除一个元素时,应该将 j 减一,因为接下来要从当前位置重新开始计数。

以下是修改后的代码:

#include<iostream>
#include"sqlist.h"
using namespace std;

int main()
{
    int n, m, z = 0;
    cin >> n >> m;
    int* a = new int[n];
    for (int i = 1; i <= n; i++)
    {
        a[i - 1] = i;
    }
    SqList* l;
    CreateList(l, a, n);
    int j = 0, y = 0;
    int e = 0;
    while (!ListEmpty(l))
    {
        j = (j + m - 1) % n; // 计算要删除的元素的下标
        ListDelete(l, j + 1, e); // 删除元素
        cout << e << " "; // 输出被删除的元素
        n--; // 更新链表长度
        y++; // 记录已经删除的元素个数
        j = j % n; // 重新计算下一次要删除的元素的下标
    }
    return 0;
}

在修改后的代码中,我们使用一个循环变量 j 来表示当前要删除的元素的下标,每次计算下一个要删除的元素的下标时使用 (j + m - 1) % n 计算,删除元素后更新链表长度 n,同时将 j 重新计算为下一次要删除的元素的下标,即 j % n。此外,我们还添加了一个变量 y 来记录已经删除的元素的个数,以便判断循环结束的条件。


如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

  • 这个问题的回答你可以参考下: https://ask.csdn.net/questions/7671244
  • 你也可以参考下这篇文章:整合一些我认知的几种编程语言
  • 除此之外, 这篇博客: 内存的申请与释放中的 首先我们有两个问题 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
    • malloc()申请1G的内存能否成功?判断依据是什么?
    • 申请了一块空间没有free,进程就结束了,那么空间被回收了吗?

    我们写一段代码来申请1G空间试一试

    #include<stdio.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<string.h>
    #include<assert.h>
    
    int main()
    {
    	char *s = (char*)malloc(1024*1024*1024);
    	assert(s! NULL);
    
    	printf("main over\n");
    	exit(0);
    }
    

    这是我们执行程序前的资源情况
    在这里插入图片描述
    这是运行程序后
    在这里插入图片描述
    我们发现好像并没有太大的区别产生,这是因为我们申请内存后会在虚拟内存上进行划分,但是只有在真的使用这块空间的时候才会真正在分配物理内存

    我们将代码进行修改

    memset(s,0,1024*1024*1024);
    

    我们添加这样一段代码,让我们申请到的空间进行清零
    再次执行
    在这里插入图片描述
    内存占用增加,随后程序结束,内存释放 (运行过程中,需要对不用的空间进行free,而程序结束会自动将占用的内存释放)

  • 您还可以看一下 刘建行老师的非计算机专业,转行程序员?我可以帮你课程中的 引言小节, 巩固相关知识点