没怎么写过C代码, 请大家多多批评
这个也不是用程序实现功能, 主要是作为辅助判断的工具
题目来自这里: http://blog.csdn.net/orbit/article/details/6994575
没有细看原作者的解决方案....不过根据做这个题的过程, 有下面思路可以设计程序解决:
1. 设定一个肯定满足的解集(这里我们就是列出了所有的可能性)
2. 将提示进行抽象, 归纳为几种类型的过滤器
3. 轮询用过滤器循环检查, 直到运行一次所有过滤器不会对数据产生修改, 结束
此时就应该是最终结果了.
/**
* author: selfimpr
* mail: lgg860911@yahoo.com.cn
* blog: http://blog.csdn.net/lgg201
* 问题描述: 5人, 住5间房. 5人不同国家, 5房不同颜色, 5人不同宠物, 5人不同饮品, 5人抽不同烟, 满足下面条件
* (1) 英国人住在红色的房子里;
* (2) 瑞典人养狗作为宠物;
* (3) 丹麦人喝茶;
* (4) 绿房子紧挨着白房子,在白房子的左边;
* (5) 绿房子的主人喝咖啡;
* (6) 抽Pall Mall牌香烟的人养鸟;
* (7) 黄色房子里的人抽Dunhill牌香烟;
* (8) 住在中间那个房子里的人喝牛奶;
* (9) 挪威人住在第一个房子里面;
* (10) 抽Blends牌香烟的人和养猫的人相邻;
* (11) 养马的人和抽Dunhill牌香烟的人相邻;
* (12) 抽BlueMaster牌香烟的人和啤酒;
* (13) 德国人抽Prince牌香烟;
* (14) 挪威人和住在蓝房子的人相邻;
* (15) 抽Blends牌香烟的人和喝矿泉水的人相邻。
* 结果:
初始化
+----------+-----------------------------+---------------------------------------+----------------------------------------------------------------------------------------------------+
| index | country | color | animal | drink | smoke |
+----------+-----------------------------+---------------------------------------+----------------------------------------------------------------------------------------------------+
| 0 | red,green,white,yellow,blue | england,sweden,denmark,norway,germany | bird,cat,dog,fish,horse | tea,coffee,milk,beer,water | pall_mall,dunhill,blends,blue_master,prince |
+----------+-----------------------------+---------------------------------------+----------------------------------------------------------------------------------------------------+
| 1 | red,green,white,yellow,blue | england,sweden,denmark,norway,germany | bird,cat,dog,fish,horse | tea,coffee,milk,beer,water | pall_mall,dunhill,blends,blue_master,prince |
+----------+-----------------------------+---------------------------------------+----------------------------------------------------------------------------------------------------+
| 2 | red,green,white,yellow,blue | england,sweden,denmark,norway,germany | bird,cat,dog,fish,horse | tea,coffee,milk,beer,water | pall_mall,dunhill,blends,blue_master,prince |
+----------+-----------------------------+---------------------------------------+----------------------------------------------------------------------------------------------------+
| 3 | red,green,white,yellow,blue | england,sweden,denmark,norway,germany | bird,cat,dog,fish,horse | tea,coffee,milk,beer,water | pall_mall,dunhill,blends,blue_master,prince |
+----------+-----------------------------+---------------------------------------+----------------------------------------------------------------------------------------------------+
| 4 | red,green,white,yellow,blue | england,sweden,denmark,norway,germany | bird,cat,dog,fish,horse | tea,coffee,milk,beer,water | pall_mall,dunhill,blends,blue_master,prince |
+----------+-----------------------------+---------------------------------------+----------------------------------------------------------------------------------------------------+
结果分布
+----------+-----------+---------+--------+---------+-------------+
| index | country | color | animal | drink | smoke |
+----------+-----------+---------+--------+---------+-------------+
| 0 | yellow | norway | cat | water | dunhill |
+----------+-----------+---------+--------+---------+-------------+
| 1 | blue | denmark | horse | tea | blends |
+----------+-----------+---------+--------+---------+-------------+
| 2 | red | england | bird | milk | pall_mall |
+----------+-----------+---------+--------+---------+-------------+
| 3 | green | germany | fish | coffee | prince |
+----------+-----------+---------+--------+---------+-------------+
| 4 | white | sweden | dog | beer | blue_master |
+----------+-----------+---------+--------+---------+-------------+
* 思路: 初始假定5间房, 所有条件全部满足, 然后根据提示进行排除
* 实现: 目前程序只是一个辅助手段, 还是靠手动执行判断的
* 改进方案: 将15个条件抽象为过滤器, 逐遍扫描过滤器, 直到所有过滤器执行一轮不会使结果发生变化
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#define HOUSE_SIZE 5
#define CONDITION_NUM 5
#define OUTPUT_FORMAT "%-10s|%-40s|%-40s|%-40s|%-40s|%-40s\n"
const char *colors[] = {"red", "green", "white", "yellow", "blue"};
const char *countrys[] = {"england", "sweden", "denmark", "norway", "germany"};
const char *animals[] = {"bird", "cat", "dog", "fish", "horse"};
const char *drinks[] = {"tea", "coffee", "milk", "beer", "water"};
const char *smokes[] = {"pall_mall", "dunhill", "blends", "blue_master", "prince"};
struct house {
int color[CONDITION_NUM + 1];
int country[CONDITION_NUM + 1];
int animal[CONDITION_NUM + 1];
int drink[CONDITION_NUM + 1];
int smoke[CONDITION_NUM + 1];
};
//数据的初始化/销毁/打印
struct house *houses_init();
void houses_dest(struct house *);
void houses_show(struct house *, char *);
void house_show(struct house *, int);
void items_show(const char **, const int *, const char *);
//数据处理
void items_remove(int *, ...);
void item_remove(int *, int);
void item_remain(int *, int);
//提示信息
void split_tips(char *);
void main(void) {
struct house *houses;
//初始化数据
houses = houses_init();
//展示初始化数据
houses_show(houses, "初始化");
//删除测试
//items_remove(houses->color, 1, 3, -1);
//houses_show(houses, "删除测试");
//剩余测试
//item_remain(houses->country, 1);
//houses_show(houses, "剩余测试");
//条件过滤
//挪威人在第一个房子
item_remain(houses[0].country, 3);
item_remove(houses[1].country, 3);
item_remove(houses[2].country, 3);
item_remove(houses[3].country, 3);
item_remove(houses[4].country, 3);
//中间房子的喝牛奶
item_remove(houses[0].drink, 2);
item_remove(houses[1].drink, 2);
item_remain(houses[2].drink, 2);
item_remove(houses[3].drink, 2);
item_remove(houses[4].drink, 2);
//挪威人和住在蓝房子的人相邻
item_remove(houses[0].color, 4);
item_remain(houses[1].color, 4);
item_remove(houses[2].color, 4);
item_remove(houses[3].color, 4);
item_remove(houses[4].color, 4);
//绿色房子的主人喝咖啡
item_remove(houses[2].color, 1);
//绿色房子紧挨着白房子, 在白房子的左边
item_remove(houses[0].color, 1);
item_remain(houses[3].color, 1);
item_remain(houses[4].color, 2);
item_remove(houses[0].color, 2);
item_remove(houses[2].color, 2);
//挪威人在第一个房子
//英国人住在红色的房子
//只剩下0,2两个房子颜色不确定
item_remove(houses[0].color, 0);
item_remain(houses[2].color, 0);
item_remain(houses[2].country, 0);
item_remove(houses[1].country, 0);
item_remove(houses[3].country, 0);
item_remove(houses[4].country, 0);
//绿房子的主人喝咖啡
item_remove(houses[0].drink, 1);
item_remove(houses[1].drink, 1);
item_remove(houses[2].drink, 1);
item_remain(houses[3].drink, 1);
item_remove(houses[4].drink, 1);
//黄色房子的主人抽Dunhill香烟
item_remain(houses[0].smoke, 1);
item_remove(houses[1].smoke, 1);
item_remove(houses[2].smoke, 1);
item_remove(houses[3].smoke, 1);
item_remove(houses[4].smoke, 1);
//养马的人和抽Dunhill的人相邻
item_remove(houses[0].animal, 4);
item_remain(houses[1].animal, 4);
item_remove(houses[2].animal, 4);
item_remove(houses[3].animal, 4);
item_remove(houses[4].animal, 4);
//丹麦人喝茶
item_remove(houses[3].country, 2);
//抽Blends香烟的人和喝矿泉水的人相邻
item_remove(houses[4].smoke, 2);
//抽BlueMaster香烟的人喝啤酒
item_remove(houses[2].smoke, 3);
item_remove(houses[3].smoke, 3);
item_remove(houses[0].drink, 3);
//丹麦人喝茶
item_remain(houses[0].drink, 4);
item_remove(houses[1].drink, 4);
item_remove(houses[4].drink, 4);
//抽Blends香烟的人和喝矿泉水的相邻
item_remain(houses[1].smoke, 2);
item_remove(houses[2].smoke, 2);
item_remove(houses[3].smoke, 2);
item_remain(houses[4].smoke, 3);
//德国人抽Prince
item_remove(houses[2].smoke, 4);
item_remain(houses[3].smoke, 4);
item_remain(houses[3].country, 4);
item_remove(houses[1].country, 4);
item_remove(houses[4].country, 4);
//抽BlueMaster香烟的人喝啤酒
item_remain(houses[4].drink, 3);
item_remove(houses[1].drink, 3);
//丹麦人喝茶
item_remain(houses[1].country, 2);
item_remove(houses[4].country, 2);
//抽PallMall香烟的人养鸟
item_remain(houses[2].animal, 0);
item_remove(houses[0].animal, 0);
item_remove(houses[3].animal, 0);
item_remove(houses[4].animal, 0);
//瑞典人养狗
item_remain(houses[4].animal, 2);
item_remove(houses[0].animal, 2);
item_remove(houses[3].animal, 2);
//抽Blends香烟的和养猫的人相邻
item_remain(houses[0].animal, 1);
item_remove(houses[3].animal, 1);
houses_show(houses, "过滤后");
houses_dest(houses);
}
struct house *houses_init() {
struct house *houses;
int i = 0, j;
houses = (struct house *)calloc(HOUSE_SIZE, sizeof(struct house));
for ( i = 0; i < HOUSE_SIZE; i ++ ) {
for ( j = 0; j < CONDITION_NUM; j ++ ) {
(houses + i)->color[j] = j;
(houses + i)->country[j] = j;
(houses + i)->animal[j] = j;
(houses + i)->drink[j] = j;
(houses + i)->smoke[j] = j;
}
(houses + i)->color[j] = -1;
(houses + i)->country[j] = -1;
(houses + i)->animal[j] = -1;
(houses + i)->drink[j] = -1;
(houses + i)->smoke[j] = -1;
}
return houses;
}
void houses_dest(struct house *houses) {
free(houses);
}
void houses_show(struct house *houses, char *msg) {
int i;
if ( msg != NULL ) {
split_tips(msg);
}
printf(OUTPUT_FORMAT, "index", "country", "color", "animal", "drink", "smoke");
for ( i = 0; i < HOUSE_SIZE; i ++ ) {
house_show(houses + i, i);
}
printf("\n\n");
}
void house_show(struct house *house, int index) {
printf("%- 10d", index);
items_show(colors, house->color, "|");
items_show(countrys, house->country, "|");
items_show(animals, house->animal, "|");
items_show(drinks, house->drink, "|");
items_show(smokes, house->smoke, "|");
printf("\n");
}
void items_show(const char **names, const int *items, const char *msg) {
if ( msg != NULL ) printf("%s", msg);
int i;
char *tmp = malloc(sizeof(char) * 1024);
char *tmp_s = tmp;
for ( i = 0; *(items + i) != -1; i ++ ) {
tmp += sprintf(tmp, "%s", *(names + *(items + i)));
if ( *(items + i + 1) != -1 ) tmp += sprintf(tmp, ",");
}
printf("%-40s", tmp_s);
}
void items_remove(int *items, ...) {
int value;
va_list va;
va_start(va, items);
while ( (value = va_arg(va, int)) != -1 ) {
item_remove(items, value);
}
va_end(va);
}
void item_remove(int *items, int item) {
int i;
for ( i = 0; *(items + i) != -1; i ++ ) {
if ( item == *(items + i ) ) break;
}
for ( ; *(items + i ) != -1; i ++ ) {
*(items + i) = *(items + i + 1);
}
}
void item_remain(int *items, int item) {
int i;
for ( i = 0; *(items + i) != -1; ) {
if ( item != *(items + i) ) item_remove(items, *(items + i));
else i ++;
}
}
void split_tips(char *msg) {
printf("------------------------------------------%s---------------------------------------\n", msg);
}