数据结构与算法分析1.2练习:编写一个程序解决字谜问题

只是讨论4行4列情况(书中情况)

原来是将预先写好的单词存在字符串中,但考虑到当单词较多时,可以将单词文本以txt形式存储

使用文件处理操作将文本中内容读入字符串words中,通过字符串函数查找是否存在单词

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<errno.h>
using namespace std;
const char input[4][4] = { {'t','h','i','s'},
                           {'w','h','t','s'},
                           {'o','a','a','g'} ,
                           {'f','g','d','t'} };
//char words[] = " this fat that two ";
char words[1024];
char s1[10], s2[10], s3[10], s4[10];
int a, b, c, d, h,t = 0,res=0;
int pd1[1000],pd2[1000],pd3[1000],pd4[1000];//记录是否选过该字母/避免重复
//计算阶乘
int factorial(int x)
{
    int ret = 1;
    for (int i = 2; i <= x; i++)
        ret *= i;
    return ret;
}
//全排列查找
void search(int m, char* s1, int* a)
{
    int p = factorial(m), q = 1;
    while (!strstr(words, s1) && q <= p)//(计算阶乘,全排列次数是否全列举完)
        next_permutation(s1, s1 + m), q++;//进行全排列
    char* x = strstr(words, s1);//  该函数返回的是查找到的单词地址
    h = x - words;//锁定位置(为避免歧义,文本中每个单词前后均设为空格)
    if (x &&  words[h-1] == ' ' && words[h+m] == ' '){
        printf("word %d :  %s\n", ++t, s1);
        *a = 1;//节省时间,表明在此行/列中已经查找到正确的单词,避免重复查找
        res=1;//说明存在正确的单词
    }
    return;
}
void findtransverse(int k,int m, int trans)//横向  单词数  行数
{

    if (k == m&&!a) { search(m, s1, &a); return;}
    for (int i = k; i < 4; i++) {
        if (!pd1[i]) {//避免重复
            pd1[i] = 1;
            s1[k] = input[trans][i];
            findtransverse(k + 1, m, trans);
            pd1[i] = 0; //置为0  
        }
    }
}
void findvertical(int k, int m, int ver)//竖向 //4 0 0
{
    if (k == m && !b) { search(m, s2, &b); return; }
    for (int i = k; i < 4; i++)
    {
        if (!pd2[i]) {
            pd2[i] = 1;
            s2[k] = input[i][ver];
            findvertical(k + 1, m, ver);
            pd2[i] = 0;
        }
    }
}
void finddiagonal1(int k,int m)//对角线
{
    if (k == m && !c) { search(m, s3, &c); return; }
    for (int i = k; i < 4; i++) {
        if (!pd3[i]) {
            pd3[i] = 1;
            s3[k] = input[i][i];
            finddiagonal1(k + 1, m);
            pd3[i] = 0;
        }
    }
}
void finddiagonal2(int k,int m)//对角线  3
{
    if (k == m && !d) { search(m, s4, &d); return; }
    for (int j = k; j < 4; j++){
        if (!pd4[j]) {
            pd4[j] = 1;
            s4[k] = input[3 - j][j];
            finddiagonal2(k + 1, m);
            pd4[j] = 0;
        }
    }
}
//重新清理0
void reinit(char* p, int j)
{
    for (int i = 0; i < j; i++)
        p[i] = 0;
}
int main()
{
    FILE* pf = fopen("D:\\作业\\字谜游戏文档存储.txt", "r");
    if (pf == NULL)
    {
        perror("open the file");
        return 0;
    }
    fgets(words, 1024, pf);//将文本内容读入字符串
    for (int i = 0; i < 4; i++) //决定横向/竖向查找的行和列
     {
        a = 0, b = 0, c = 0, d = 0;
        for (int j = 4; j >= 1; j--)   //决定单词字母数目
          {
            if (!a) findtransverse(0,j, i), reinit(s1, j);//横向
            if (!b) findvertical(0,j, i), reinit(s2, j);//竖向
            if (i==0&&!c) finddiagonal1(0,j), reinit(s3, j);//左上-右下(对角线方向的只用找一次)
            if (i==0&&!d) finddiagonal2(0,j), reinit(s4, j);//左下-右上(不同于横向竖向与行数/列数相关,只用找一次)
        }
    }
    if (!res)  printf( "不存在符合条件的单词");
    fclose(pf);
    pf = NULL;
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值