0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

C語言-有趣的約瑟夫問題及解決辦法

嵌入式那些事 ? 來源:嵌入式那些事 ? 2023-09-23 11:13 ? 次閱讀

今天給大家講講約瑟夫問題是什么,并且我提供了一種約瑟夫問題的解決辦法。對(duì)于不知道約瑟夫是誰的人來說,就更不用提什么是約瑟夫問題了。那么問題來了,約瑟夫是誰,約瑟夫問題又是個(gè)什么東西。

首先來個(gè)解釋吧,約瑟夫問題,有時(shí)也稱為約瑟夫置換,是一個(gè)出現(xiàn)在計(jì)算機(jī)科學(xué)和數(shù)學(xué)中的問題。特別是對(duì)于學(xué)習(xí)過數(shù)據(jù)結(jié)構(gòu)的人來說,在書上看到解決這個(gè)問題的題目,可能都不下5遍吧。在計(jì)算機(jī)編程算法中,類似的問題又稱為約瑟夫環(huán)或者丟手絹問題。

約瑟夫(Josephus)是誰,約瑟夫是著名的猶太歷史學(xué)家,那么約瑟夫問題又是個(gè)什么東西呢。其實(shí)我并不太清楚約瑟夫的什么生平經(jīng)歷,但是關(guān)于約瑟夫問題,倒是有一個(gè)小故事給大家講一講,這個(gè)故事就是約瑟夫問題的原型。好了,下面來個(gè)大家講故事了,據(jù)說在羅馬人占領(lǐng)喬塔帕特后,39個(gè)猶太人與Josephus及他的朋友躲到一個(gè)洞中,39個(gè)猶太人決定寧愿死也不要被敵人抓到,于是決定了一個(gè)自殺方式,41個(gè)人排成一個(gè)圓圈,由第1個(gè)人開始報(bào)數(shù),每報(bào)數(shù)到第3人該人就必須自殺,然后再由下一個(gè)重新報(bào)數(shù),直到所有人都自殺身亡為止。然而Josephus和他的朋友并不想遵從。首先從一個(gè)人開始,越過k-2個(gè)人(因?yàn)榈谝粋€(gè)人已經(jīng)被越過),并殺掉第k個(gè)人。接著,再越過k-1個(gè)人,并殺掉第k個(gè)人。這個(gè)過程沿著圓圈一直進(jìn)行,直到最終只剩下一個(gè)人留下,這個(gè)人就可以繼續(xù)活著。問題是,給定了和,一開始要站在什么地方才能避免被處決?Josephus要他的朋友先假裝遵從,他將朋友與自己安排在第16個(gè)與第31個(gè)位置,于是逃過了這場(chǎng)死亡游戲。

從上面的故事,大家至少可以知道,約瑟夫雖然是個(gè)歷史學(xué)家,但是他的數(shù)學(xué)學(xué)的也不賴嘛。

約瑟夫問題并不難,求解的方法也非常的多,我這里提供一個(gè)循環(huán)鏈表的解決方法,為什么用循環(huán)鏈表,因?yàn)槲铱茨莻€(gè)故事里面的人都是手拉手圍成一個(gè)圓圈的嘛。

下面是我寫的程序源代碼,大家看看,就知道是怎么解決的了:

注:可以通過修改mian()函數(shù)中的StartCount,length這3個(gè)參數(shù)來改變游戲的規(guī)則,大家可以試試。

#include
#include

/*
*功能:約瑟夫問題解決辦法(循環(huán)鏈表解決)
*By:AilsonJack
*Date:2014.05.24
*/
#defineerror0
#defineok1

typedefintElementType;
typedefstructCycleListNodeNode;
typedefstructCycleListNode*ptrNode;

structCycleListNode//循環(huán)鏈表結(jié)點(diǎn)
{
ElementTypedata;//數(shù)據(jù)區(qū)
ptrNodenext;//指向下一個(gè)結(jié)點(diǎn)
};

//函數(shù)聲明
//約瑟夫問題解決辦法(循環(huán)鏈表解決)
voidJosephus(ptrNodelist,intstart,intcount,intlength);

//創(chuàng)建循環(huán)鏈表頭結(jié)點(diǎn)
intCycleList_CreateNode(ptrNode*list);

//初始化循環(huán)鏈表,并且最后丟掉鏈表頭結(jié)點(diǎn),鏈表的數(shù)據(jù)為1->length
voidCycleList_Init(ptrNode*list,intlength);

//刪掉循環(huán)鏈表中從表頭數(shù)的第position個(gè)位置的數(shù)據(jù)
//最終將頭結(jié)點(diǎn)變?yōu)閯h除前那個(gè)結(jié)點(diǎn)的下一個(gè)結(jié)點(diǎn)
voidCycleList_Delete(ptrNode*list,intposition);

//查找循環(huán)鏈表中數(shù)據(jù)元素是Start的結(jié)點(diǎn)的位置,并且將該節(jié)點(diǎn)設(shè)為新的起始結(jié)點(diǎn)s
voidCycleList_Find(ptrNode*list,ElementTypeStart);

//打印循環(huán)鏈表中的數(shù)據(jù)
voidPrin_CycleList(ptrNodelist,intlength);

intmain(void)
{
intStart=1;//起始計(jì)數(shù)位置
intCount=3;//第Count個(gè)位置的結(jié)點(diǎn)出局
intlength=41;//循環(huán)鏈表的長(zhǎng)度
ptrNodelist;

CycleList_CreateNode(&list);
CycleList_Init(&list,length);
Prin_CycleList(list,length);
Josephus(list,Start,Count,length);

while(1)
{
}

return0;
}

//約瑟夫問題解決辦法(循環(huán)鏈表解決)
voidJosephus(ptrNodelist,intstart,intcount,intlength)
{
inti=1;

CycleList_Find(&list,start);
printf("
約瑟夫問題解決開始....
");

while(i<=?length)
????{
????????CycleList_Delete(&list,count);
i++;
}

printf("
約瑟夫問題解決結(jié)束
");
}

//創(chuàng)建循環(huán)鏈表頭結(jié)點(diǎn)
intCycleList_CreateNode(ptrNode*list)
{
*list=(ptrNode)malloc(sizeof(structCycleListNode));
if(*list==NULL)
{
printf("OutofSpace...
");
returnerror;
}

(*list)->next=NULL;

returnok;
}//初始化循環(huán)鏈表,并且最后丟掉鏈表頭結(jié)點(diǎn),鏈表的數(shù)據(jù)為1->length
voidCycleList_Init(ptrNode*list,intlength)
{
inti=1;
ptrNodenewNode;
ptrNodeFirstNode;
FirstNode=*list;

while(i<=?length)//i從1到length
{
newNode=(ptrNode)malloc(sizeof(structCycleListNode));
newNode->data=i;
(*list)->next=newNode;
(*list)=newNode;
i++;
}

(*list)->next=FirstNode->next;
*list=FirstNode->next;
}

//刪掉循環(huán)鏈表中從表頭數(shù)的第position個(gè)位置的數(shù)據(jù)
//最終將頭結(jié)點(diǎn)變?yōu)閯h除前那個(gè)結(jié)點(diǎn)的下一個(gè)結(jié)點(diǎn)
voidCycleList_Delete(ptrNode*list,intposition)
{
inti=1;
ptrNodetmp;

if(position==1)
{
tmp=*list;
while(tmp->data!=(*list)->next->data)
{
*list=(*list)->next;
}
printf("%d",(*list)->next->data);
(*list)->next=tmp->next;
*list=tmp->next;
free(tmp);
tmp=NULL;
}
else
{
while(i-1))
{
(*list)=(*list)->next;
i++;
}

tmp=(*list)->next;
printf("%d",tmp->data);
(*list)->next=(*list)->next->next;
free(tmp);
tmp=NULL;
*list=(*list)->next;
}
}

//查找循環(huán)鏈表中數(shù)據(jù)元素是Start的結(jié)點(diǎn)的位置,并且將該節(jié)點(diǎn)設(shè)為新的起始結(jié)點(diǎn)
voidCycleList_Find(ptrNode*list,ElementTypeStart)
{
while((*list)->data!=Start)
{
*list=(*list)->next;
}
}

//打印循環(huán)鏈表中的數(shù)據(jù)
voidPrin_CycleList(ptrNodelist,intlength)
{
inti=1;

printf("打印循環(huán)鏈表...
");

while(i<=?length)
????{
????????printf("%d",list->data);
list=list->next;
i++;
}

printf("
結(jié)束打印
");
}

下面是程序的運(yùn)行結(jié)果:

345b147e-59b7-11ee-939d-92fbcf53809c.png

2015-03-31_165155

以上就是對(duì)約瑟夫問題的解決方法啦,大家有不明白的可以留言喲。


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7594

    瀏覽量

    135864
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4278

    瀏覽量

    62325
  • 數(shù)據(jù)結(jié)構(gòu)

    關(guān)注

    3

    文章

    569

    瀏覽量

    40072

原文標(biāo)題:C語言-有趣的約瑟夫問題及解決辦法

文章出處:【微信號(hào):嵌入式那些事,微信公眾號(hào):嵌入式那些事】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    華碩筆記本聲卡驅(qū)動(dòng)無法安裝的解決辦法

    華碩筆記本聲卡驅(qū)動(dòng)無法安裝的解決辦法
    發(fā)表于 01-18 10:10 ?3529次閱讀

    聲卡硬件維修的常見問題及解決辦法

    聲卡硬件維修的常見問題及解決辦法 常見故障一:聲卡無聲   出現(xiàn)這種故障常見的原因有:
    發(fā)表于 02-23 14:25 ?2513次閱讀

    誤碼特性,誤碼產(chǎn)生的機(jī)理及解決辦法

    誤碼特性,誤碼產(chǎn)生的機(jī)理及解決辦法
    發(fā)表于 03-19 17:10 ?2244次閱讀

    UPS電源輸入跳閘淺析及解決辦法

    UPS電源輸入跳閘淺析及解決辦法解析
    發(fā)表于 11-10 16:42 ?89次下載
    UPS電源輸入跳閘淺析及<b class='flag-5'>解決辦法</b>

    Matlab編程常見錯(cuò)誤與解決辦法

    Matlab編程常見錯(cuò)誤與解決辦法求人不如求己
    發(fā)表于 03-16 15:58 ?0次下載

    壓榨輥軸承位磨損有哪些解決辦法

    壓榨輥軸承位磨損有哪些解決辦法
    發(fā)表于 01-19 09:45 ?4次下載

    ESP32勘誤表及解決辦法

    電子發(fā)燒友網(wǎng)站提供《ESP32勘誤表及解決辦法.pdf》資料免費(fèi)下載
    發(fā)表于 09-23 11:51 ?0次下載
    ESP32勘誤表及<b class='flag-5'>解決辦法</b>

    電腦右鍵管理打開失敗的解決辦法

    此電腦右鍵管理打不開怎么辦 電腦右鍵管理打開失敗的解決辦法
    發(fā)表于 09-28 09:56 ?0次下載

    J-Link連接MCU失敗解決辦法

    J-Link連接MCU失敗解決辦法
    的頭像 發(fā)表于 10-18 17:43 ?1040次閱讀
    J-Link連接MCU失敗<b class='flag-5'>解決辦法</b>

    硬盤故障的3個(gè)終極解決辦法

    電子發(fā)燒友網(wǎng)站提供《硬盤故障的3個(gè)終極解決辦法.pdf》資料免費(fèi)下載
    發(fā)表于 10-20 10:46 ?0次下載
    硬盤故障的3個(gè)終極<b class='flag-5'>解決辦法</b>

    細(xì)碎機(jī)軸承位磨損問題的解決辦法

    【設(shè)備故障】細(xì)碎機(jī)軸承位磨損問題的解決辦法
    發(fā)表于 10-27 16:36 ?0次下載

    研華工控機(jī)故障及解決辦法(四)

    研華工控機(jī)故障及解決辦法(四)
    的頭像 發(fā)表于 11-06 15:55 ?1073次閱讀
    研華工控機(jī)故障及<b class='flag-5'>解決辦法</b>(四)

    Protel99 與WIN10系統(tǒng)沖突解決辦法

    PROTEL99 與WIN10系統(tǒng)沖突解決辦法
    的頭像 發(fā)表于 11-20 09:30 ?3790次閱讀
    Protel99 與WIN10系統(tǒng)沖突<b class='flag-5'>解決辦法</b>

    Profinet IO通信故障的解決辦法

    Profinet IO通信故障可能由多種原因引起,以下是一些常見的通信故障及其解決辦法
    的頭像 發(fā)表于 03-08 11:27 ?1037次閱讀

    常見MCU故障及解決辦法

    微控制器單元(MCU)是現(xiàn)代電子設(shè)備中的核心組件,負(fù)責(zé)處理和控制各種功能。然而,由于各種原因,MCU可能會(huì)出現(xiàn)故障。以下是一些常見的MCU故障及其解決辦法: 1. 電源問題 故障現(xiàn)象: MCU無法
    的頭像 發(fā)表于 11-01 13:41 ?256次閱讀