微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C中的循环数组和消除,如何返回最后一个“活”元素索引?

如何解决C中的循环数组和消除,如何返回最后一个“活”元素索引?

我正在尝试编写一个代码来模拟 circle 固定大小的拥有一把剑的人。与当前 index 最接近的“活人”将被淘汰,剑将传递给下一个活人(在被杀死的人之后),依此类推。

我希望它没有链表。

示例: 3人一组: arr[0] = 1,arr[1] = 1,arr[2] = 1

第一回合:

  • arr[0] KILLS arr[1] and the sword gets PASSED to arr[2]

第一回合后的元素值:

arr[0] = 1,arr[1] = 0,arr[2] = 1

第二回合:

  • arr[2] KILLS arr[0] and stays the last player

第二回合后的元素值:

arr[0] = 0,arr[2] = 1

  • arr[2]'s index gets returned by the main function

我想到的是:

  • 数组
  • 将所有元素的值设置为 1
  • 每次循环检查if (1 == arr[i])
  • 一个旗子来决定是杀了这个人还是直接把剑传给这个人。
  • 返回当前索引,该索引表示最后一个活着的玩家的索引。

例如,假设我们的组中有 5 个人: [1] [1] [1] [1] [1]

第一轮

give_sword = 0

i = 0 不输入第一个 if,因为 give_sword 不是 1。 它进入第二个 if,并使用函数 findClosestLivingPerson 找到最近的活人,并获取他的索引并将其值设置为 0(== 杀死最近的活人)。 它将 give_sword 设置为 1

减少 players_counter 并检查是否只剩下一名玩家。如果不是,则继续循环。

这是我的代码

#include <stdio.h>

int findClosestLivingPerson(int arr[],int index,int group_size);


int main (int argc,char *argv[])
{
    
    int group_size = 0,players_counter = 0;
    int i = 0,give_sword = 0;
    int arr[100] = {0};
    
    printf("Enter group size: \n");
    scanf("%d",&group_size);
    
    for (i = 0; i < group_size; i++)
    {
         arr[i] = 1;
    }
   
    players_counter = group_size;
    
        for (i = 0; i < group_size; (i+1) % group_size)
        {
            if (1 == arr[i])
            {
                if(1 == give_sword) /* should give sword,not to kill */
                {
                    give_sword = 0;
                }
                else /* should be killed */
                {
                    arr[findClosestLivingPerson(arr,i,group_size)] = 0;
                    give_sword = 1;
                    --players_counter;
                    if (players_counter == 1)
                    { 
                        break;
                    }
                }
            }
        }
    printf("Winner is %d ",i);
    return 0;
}

int findClosestLivingPerson(int arr[],int group_size)
{
    for (; index < group_size; (index+1) % group_size)
    {
        if (arr[index] == 1)
        return index;
    }
    return 0;
}

编译器说:

函数‘main’中:last_man.c:23:43:警告:没有语句 效果 [-Wunused-value] 23 | for (i = 0; i

last_man.c:在函数‘findClosestLivingPerson’中:last_man.c:49:42: 警告:语句无效 [-Wunused-value] 49 |为了 (; 索引

(index+1) % group_size 旨在通过此数组循环。

解决方法

正如编译器所说,strings 无效。它计算 (i+1) % group_size 和 1 之和的余数。之后,它对结果不做任何事情。

i 语句的第三部分只是一个被计算的表达式。它不会自动更新循环索引或执行任何其他操作。如果你想让它更新 for,你必须写一个作业,比如 i

,

我认为您误解了 for 循环的工作原理。

格式应该是这样的:

for( initialization,condition,iteration )

示例:

for( int i = 0; i < size; i = i + 1 )

(i + 1) % group_size 不是迭代(它不是将结果分配给 i ),您真正想做的是

i = ( i + 1 ) % group_size;

同样适用于第二个警告。

,

我建议采用不同的方法。让我们以一种能产生漂亮代码的方式来做到这一点。

struct actor {
    int label;
    struct actor *next;
};

使用这个结构,我们可以制作一个漂亮的链表并将其循环回:

int n = 5;
int i;

struct actor *actors = calloc(n,sizeof *actors);
for (i = 0; i < n - 1; i++) {
    actors[i].label = i;
    actors[i].next = &actors[i+1];
}
actors[i].label = i;
actors[i].next = &actors[0];

好的,现在我们可以指定第一个杀手:

struct actor *k = actors;

我们还需要一个kill函数:

struct actor *kill(struct actor *a)
{
    if (a->next != a) {
        printf("%d kills %d\n",a->label,a->next->label);
        a->next = a->next->next;
    } else {
        printf("%d is last man standing\n",a->label);
        a->next = NULL;
    }
    return a->next;
}

这是做什么的:它从循环链表中删除下一个人(因为那个人就是被杀死的人)。下一个人的查找时间始终相同。

一切就绪后,我们就可以开始狂欢了:

while (k) {
    k = kill(k);
}

无论如何,这都不是完美的代码,但它是一个很好的例子,说明如果您在设置上付出一些努力,您可以如何使算法变得非常简单。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。