Google方程式
Posted coolcpp
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Google方程式相关的知识,希望对你有一定的参考价值。
书名:《算法的乐趣》
1. 问题描述:
有一个由字符组成的等式:WWWDOT - GOOGLE = DOTCOM,每个字符代表一个0-9之间的数字,并且这三组字母组成的都是合法的数字,不能以0开头。找出一组字符和数字的对应关系,使满足这个式子。
2. 解题思路:
首先定义一个表示字符属性的结构:
typedef struct{
char c; //字母本身
int value; //字母代表的数字
bool leading; //是否是数字的最高位
}CHAR_ITEM;
这样,本题可以初始化为:
CHAR_ITEM charItem[] = {
{‘W‘, -1, true }, {‘D‘, -1, true }, {‘O‘, -1, false },
{‘T‘, -1, false }, {‘G‘, -1, true }, {‘L‘, -1, false },
{‘E‘, -1, false }, {‘C‘, -1, false }, {‘M‘, -1, false } };
由于这是一个组合问题,两个字母不能为相同的数字,所以,需要对每个数字做一个标记,表示其是否已被使用。
typedef struct{
bool used; //是否已被使用
int value; //值
}CHAR_VALUE;
穷举的搜索算法采用递归的方式进行组合枚举, 按照charItem中的顺序,逐个对每个字符进行数字遍历:
void SearchingResult(CHAR_ITEM ci[], CHAR_VALUE cv[],
int index, CharListReadyFuncPtr callback)
{
if(index == max_char_count)
{
callback(ci);
return;
}
for(int i = 0; i < max_number_count; ++i)
{
if(IsValueValid(ci[index], cv[i]))
{
cv[i].used = true; //标记为已用
ci[index].value = cv[i].value; //用0-9来测
SearchingResult(ci, cv, index + 1, callback);
cv[i].used = false; //清除标记
}
}
}
开头字母为‘W‘,‘G‘,‘D‘,所以这三个数字不能为0,在IsValueValid中实行判断。index用来标识字符索引,每次递归调用对索引为index的字符进行数字遍历。当index等于字符个数时,表示所有的字符都已经指定了对应的数字,便可调用callback进行结果判断。
IsValueValid的实现:
bool IsValueValid(CharItem ci, CharValue cv)
{
if(cv.used)
{
return false;
}
if(ci.leading && (cv.value == 0))
{
return false;
}
return true;
}
callback函数的实现:
void OnCharListReady(CHAR_ITEM ci[])
{
char *minuend = "WWWDOT";
char *subtrahend = "GOOGLE";
char *diff = "DOTCOM";
int m = MakeIntegerValue(ci, minuend);
int s = MakeIntegerValue(ci, subtrahend);
int d = MakeIntegerValue(ci, diff);
if((m - s) == d)
{
std::cout << m << " - " << s << " = " << d << std::endl;
}
}
MakeIntegerValue用于将组成的数字转化为6位的值,其实现为:
int MakeIntegerValue(CharItem ci[max_char_count], char *chars)
{
assert(chars);
int value = 0;
char *p = chars;
while(*p != 0)
{
CharItem *char_item = GetCharItem(ci, *P);
if(NULL == char_item)
{
return 0;
}
value = value * 10 + char_item->value;
p++;
}
return value;
}
3. 完整代码
//equa_define.h
#pragma once
typedef struct
{
char c; //字母本身
int value; //代表的数字
bool leading; //是否是最高位
}CharItem;
typedef struct
{
bool used; //是否使用过
int value; //值
}CharValue;
const int max_number_count = 10;
const int max_char_count = 9;
typedef void(*CharListReadyFuncPtr)(CharItem ci[max_char_count]);
//char_equation.h
#pragma once
#include "equa_define.h"
int MakeIntegerValue(CharItem ci[max_char_count], char *chars);
void SearchingResult(CharItem ci[max_char_count],
CharValue cv[max_number_count],
int index, CharListReadyFuncPtr callback);
//char_equation.cpp
#include <cassert>
#include "char_equation.h"
CharItem *GetCharItem(CharItem ci[max_char_count], char c)
{
for (int i = 0; i < max_char_count; ++i)
{
if (ci[i].c == c)
{
return &ci[i];
}
}
return NULL;
}
int MakeIntegerValue(CharItem ci[max_char_count], char *chars)
{
assert(chars);
int value = 0;
char *p = chars;
while (*p != 0)
{
CharItem *char_item = GetCharItem(ci, *p);
if (NULL == char_item)
{
return 0;
}
value = value * 10 + char_item->value;
p++;
}
return value;
}
bool IsValueValid(CharItem ci, CharValue cv)
{
if (cv.used)
{
return false;
}
if (ci.leading && (cv.value == 0))
{
return false;
}
return true;
}
void SearchingResult(CharItem ci[max_char_count],
CharValue cv[max_number_count],
int index, CharListReadyFuncPtr callback)
{
if (index == max_char_count)
{
callback(ci);
return;
}
for (int i = 0; i < max_number_count; ++i)
{
//检查是否是有效的数字
if (IsValueValid(ci[index], cv[i]))
{
cv[i].used = true; //标记已用
ci[index].value = cv[i].value; //用0-9来测
SearchingResult(ci, cv, index + 1, callback);
cv[i].used = false;
}
}
}
//main.cpp
#include <iostream>
#include "char_equation.h"
#include "equa_define.h"
void OnCharListReady(CharItem ci[max_char_count])
{
char *minuend = "WWWDOT";
char *subtrahend = "GOOGLE";
char *diff = "DOTCOM";
int m = MakeIntegerValue(ci, minuend);
int s = MakeIntegerValue(ci, subtrahend);
int d = MakeIntegerValue(ci, diff);
if ((m - s) == d)
{
std::cout << m << " - " << s << " = " << d << std::endl;
}
}
int main()
{
CharItem char_item[max_char_count] = {
{‘W‘, -1, true }, {‘D‘, -1, true }, {‘O‘, -1, false },
{‘T‘, -1, false }, {‘G‘, -1, true }, {‘L‘, -1, false },
{‘E‘, -1, false }, {‘C‘, -1, false }, {‘M‘, -1, false } };
CharValue char_val[max_number_count] = {
{false, 0}, {false, 1}, {false, 2}, {false, 3},
{false, 4}, {false, 5}, {false, 6}, {false, 7},
{false, 8}, {false, 9} };
SearchingResult(char_item, char_val, 0, OnCharListReady);
return 0;
}
输出:
777589 - 188103 = 589486
777589 - 188106 = 589483
以上是关于Google方程式的主要内容,如果未能解决你的问题,请参考以下文章
RecyclerView holder中的Android Google Maps动态片段