约瑟夫环问题

来源:互联网 发布:网络管理培训学校 编辑:程序博客网 时间:2024/04/28 05:27

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
#define  ERROR   -1
#define  MAX     60        //链表的最大长度
//定义结构体
struct node
{
    int id;
    int code;
    node * next;
};
//链表的创建和初始化  num为总人数  password为密码数组
node * node_initial(int num,int password[])
{
    int i;
    node *head, *p;
    head=(node*)malloc(sizeof(node));
    p=head;
    for(i=1;i<=num;i++)
    {
        p->id=i;        //赋给每个节点顺序号
        p->code=password[i-1];
        if(i<num)
        {
            p->next=(node*)malloc(sizeof(node));
            p=p->next;
        }
    }
    p->next=head;                    //构成循环链表
    return head;                    //返回头指针
}
//循环删除节点函数  head为循环链表头指针  num为总人数  ninitial_code为初始密码(或循环密码)
// order 为节点出列顺序数组
void circle(node *head,int num,int initial_code,int order[])
{
    node *p,*q;
    int i,j;
    for (p=head,i=1;i<num;i++)
        p=p->next;
        for(i=1;i<num;i++)
    {
        for(j=1;j<initial_code;j++)
            p=p->next;
        q=p->next;
        p->next=q->next;
        order[i-1]=q->id;                                                                                                                                                                                                                                                         ;
        initial_code=q->code;
        free(q);                //删除节点
        q=NULL;                    //指针为空
    }
    order[i-1]=p->id;
}
//把字符串转换成 int 型的数字
int transform(char arry[])
{
    int length,total=0,i,j=1;
    length=strlen(arry);                //测量字符串的长度
    for(i=length-1;i>=0;i--)            //从字符串尾到头计算数值
    {    
        if(arry[i]>'9'||arry[i]<'0')    //非数字的出错判断
        {
            printf("请输入正确的数字(正整数),不要包含其它字符!/n");
            return ERROR;
        }
        total+=(int)(arry[i]-'0')*j;
        j*=10;
    }
    if(total<=0)
    {
        printf("总人数和密码不能为零和负数!/n");
        return ERROR;
    }
    return (total);
}
void main(int argc,char *argv[])
{
    node *head,*t;
    int password[MAX]={0},num,initial_code,order[MAX]={0},i;
    FILE *fp;
    num=transform(argv[1]);                //获得总人数
    initial_code=transform(argv[2]);    //获得初始密码
    /*错误判断*/
    if(num>MAX)                //溢出判断
    {
        printf("溢出!总人数不要超过60人。/n");
        exit(0);
    }
    if(argc!=num+3||num==-1||initial_code==-1)            //参数匹配判断
    {    
        printf("输入的参数个数不正确或格式不对(正整数)!/n正确的格式为:文件名,初始密码,总人数N,密码1.密码2……密码N/n");
        exit(0);
    }
    for(i=1;i<=num;i++)
    {
        password[i-1]=transform(argv[i+2]);
        if(password[i-1]==-1)
            exit(0);
    }
    head=node_initial(num,password);
    circle(head,num,initial_code,order);
    //屏幕输出
    printf("节点序列号和密码为:/n/ ID       Code/n");
    for(i=1,t=head;i<=num;i++)
    {
        printf("  %d         %d/n",i,password[i-1]);
    }
    printf("/n/n出列顺序为:");
    for(i=1;i<=num;i++)
    { 
        printf("%d",order[i-1]);
        if(i!=num)
            printf(" -> ");
    }
    putchar('/n');
    //写文件
    if((fp=fopen("jonseph.txt","w"))==NULL)        //打开文件
    {
        printf("不能打开文件!/n");
        exit(0);
    }
    for(i=1;i<=num;i++) 
    {
        fprintf(fp,"ID:%d",i);
        fputc('/t',fp);
        fprintf(fp,"Code:%d",password[i-1]);
        fputc('/n',fp);
    }
    fprintf(fp,"出列顺序为:");
    for(i=1;i<=num;i++)
    {
        fprintf(fp,"%d",order[i-1]);
        if(i!=num)
            fprintf(fp," --> ");
    }
    fclose(fp);                                //关闭文件
} 
原创粉丝点击