python是世界上最好的语言

艾玛,起这个标题真不怕被人捶的(ノへ ̄、)

通过《数据结构》课程上的作业——(拓展)约瑟夫环问题的C语言版本和python版本来比较一下python是多么的简洁优雅。

Josephus来历:

据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决?Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。
平常的Josephus问题这里不再啰嗦了,以后看心情可能会补充~
直接看我们数据结构的作业吧!

题目:约瑟夫环(Joseph)

ysf_1_

问题描述:编号为1到n的n个人,按顺时针方向围成一个环(循环单链表),每人都持有一个密码(正整数)。任选一个正整数作为报数的上限(设为m),从第一个人开始按顺时针方向从1开始顺序报数,当报到m时,暂停报数并输出其标识(位序),同时将报数为m的人删除,并将他的密码作为新的m值,继续从1开始重新报数,直到m并输出。如此重复,直到全部人员都从队列中输出。编写程序,求出该出列顺序。
利用循环单链表实现这个过程,单链表的结点约定如下:
Typedef struct LNode {
int IDCode; // 人员标识
int PWD; // 人员密码
struct Lnode *next; // 指针域
} LNode, *LinkList;
其中,L为不带头结点的单链表的头指针,mi是第i个人的密码(1≤i≤n)。请按这个约定编程。
测试数据:20≤n≤30
要求:参数n和m从键盘上输入,同时输入每个人的密码,存放在数组PWD中,利用这些参数构建单链表并完成出列顺序的输出。输入的次序为人员标识(位序)。
主程序约定如下:
main () { //以下仅仅是描述,请大家按照要求完善代码
int PWD[30]; //定义密码数组
printf(“输入人员数n”);
scanf(%d,n);
printf(“输入初始密码m”);
scanf(%d,m);
p=createJoseph( int n , int PWD); //建立Joseph环,返回指向最后一个结点的指针p
printIDCode(LinkList P , int m); //输出每个人员的编号,当m大于n时,应该取n的模
printf(“以上是张三的运行结果。”);
}
提升练习

  1. 构造顺序文件存放人员密码,根据n读取前n个数据作为密码,实现以上功能;
  2. 最后建立的p结点的指针,指向了前面的某一个元素结点(未必是第一个),请按上述要求,输出环中的所有人员标识符。

人丑话不多,直接上代码,如有疑问,请在最下方留言,一定尽力回复!

C语言版:

#include<stdio.h>
#include<stdlib.h>
 
typedef struct LNode{
    int IDCoder;
    int PWD;
    struct LNode *next;
}LNode,*LinkList;
 
int PWD[100],n,m;
 
void initpwd(){
    FILE * r=fopen("data.txt","r");//把data和编译出来的应用程序放在同一个文件夹中
    if(r==NULL){
        printf("\nFailed to open the file");
        exit(1);
    }
    int i=0;
    while(fscanf(r,"%d",&PWD[i])!=EOF&&i<n){ 
    //printf("\n%d",PWD[i]); i++; 
    }
    fclose(r); 
    }
    LinkList createJoseph(int n,int PWD[]){
    //创建Josephus 
    int i=0; 
    LinkList pHead=NULL;
    pHead=(LinkList)malloc(sizeof(LNode));
    //头节点 
    pHead->PWD=PWD[i];
    pHead->IDCoder=i+1;
    pHead->next=NULL;
     
    LinkList pCurr=NULL,pPrev=NULL;
    pPrev=pHead;
    while(--n){
        pCurr=(LinkList)malloc(sizeof(LNode));
        i++;
        pCurr->PWD=PWD[i];
        pCurr->IDCoder=i+1;
        pPrev->next=pCurr;
        pPrev=pCurr;
    }
    pCurr->next=pHead;
     
    return pCurr; 
} 
 
/*void printLink(LinkList pTail){
    LinkList pCurr;
    LinkList pHead=pTail->next;
    printf("%d ",pHead->IDCoder);
    pCurr=pHead->next;
    while(pCurr!=NULL){
        if(pCurr->IDCoder==1){
            break;
        }
        printf("%d",pCurr->IDCoder);
        pCurr=pCurr->next;
    }
    printf("\n");
}*/
 
/*void printIDCode(LinkList pTail,int m,int tot){//这是我第一次写的,虽然通过了老师的测试,但是还是觉得挺烦(其实一开始如果m=1会有bug--)。
    LinkList pCurr,pPrev,pHead;
    pHead=pTail->next;
    int i=1,outNum=m;
    pCurr=pPrev=pHead;
    while(pCurr!=NULL){
        if(i==outNum){
            i=1;
            tot--;
            outNum=(pCurr->PWD-1)%tot+1;
            printf("\n%d",pCurr->IDCoder);
            pPrev->next=pCurr->next;
            free(pCurr);
            pCurr=pPrev->next;
            while(outNum==1&&tot>1){
                i=1;
                tot--;
                outNum=(pCurr->PWD-1)%tot+1;
                printf("\n%d",pCurr->IDCoder);
                pPrev->next=pCurr->next;
                free(pCurr);
                pCurr=pPrev->next;
            }
        }
        pPrev=pCurr;
        pCurr=pCurr->next;
        if(pPrev==pCurr){
            printf("\n%d",pCurr->IDCoder);
            free(pCurr);
            break;
        }
        i++;
    }
}
*/
void printIDCode(LinkList pTail,int m,int tot){//这个是问了室友之后改的
    int outNum=m; 
    LinkList pCurr,pPrev,pHead;
    pHead=pTail->next;
    pCurr=pPrev=pHead;
    while(n>0){
        if(m==1){
            for(int i=1;i<n;i++){
                pPrev=pPrev->next; 
            }
        }
        for(int i=1;i<m-1;i++){
            pPrev=pPrev->next;
        }
        pCurr=pPrev->next;
        pPrev->next=pCurr->next;
        printf("\n%d",pCurr->IDCoder);
        m=pCurr->PWD;//懒得优化了~
        free(pCurr);
        pPrev=pPrev->next;
        n--;
  }
}
 
int main(){
    LinkList pTail;
    printf("please input the number of people:");
    scanf("%d",&n); 
    printf("\nplease input pwd:");
    scanf("%d",&m);
    initpwd();
    pTail=createJoseph(n,PWD);
    printIDCode(pTail,m%n,n);
    printf("\nAuthor:KISS");
    return 0;
} 

Python版:

#!coding:utf-8
 
circle=[]#人环,每个人密码在下面列表中  第n个人对应 txt[n-1]
 
txt=[3,4,5,2,1,6,4,3,2,1,5,1,12,45,3,4,5,9,88,64,1,6,5,2,3,2,5,6,7,1,5,1,3,2,54,4,54,44,55,87,3,6,5,2,6,1,5,6,7,602,5,1,3,2,54,4,88,44,55,44,1,8,5,2,4,6,4,3,2,1,5,23,12,45,3,4,5,9,23,64,3,9,5,2,1,6,5,6,7,342,5,6,3,2,54,4,88,44,44,77]
 
n,m=raw_input('n,m:').split(' ')
 
class person():#人的属性
 
    def __init__(self,n,p):#构造函数
 
        self.number=n
 
        self.password=p
 
for i in range(int(n)):#构造人
 
    circle.append(person(i+1,txt[i]))
  
curindex=0#从第一个人开始
 
for i in range(int(n)):#开始杀人了
 
    curindex=(curindex+int(m)-1)%len(circle)#循环列表
 
    print str(circle[curindex].number)#显示被杀的人
 
    m=circle[curindex].password#根据人的密码修改m
 
    del circle[curindex]#杀人ing
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值