我有一个问题,我一直在思考,但未能找到最佳解决方案。
该应用程序适用于根据数字模式销售不同价格的特殊电话号码的公司。
所以用户有一个数字库存。并使用一些约定定义模式。例如:
当客户拿起一个号码时,该号码应与其匹配的模式匹配,当匹配一个模式时,该号码将按匹配模式的价格收费。
我的想法集中在三种可能的解决方案上:
对于我应该使用哪种方法,你们有什么建议吗?非常感谢任何提示。
修改
我很高兴收到的回复。他们都很有启发性,但到目前为止还没有解决我的问题。真实场景将具有以下条件:
到目前为止,所有提议的方法都有其自身方式的限制。我仍然想到它,所以如果你想出任何有用的打击,请与我分享!
答案 0 :(得分:2)
一个想法。 demo
$number = '987-9876';
$suffix = <<<'EOD'
0123456789 ABCDEFG 10 ABCABCD 15
9876543210 GFEDCBA 8 DCBDCBA 13
EOD;
$pattern = <<<'EOD'
~
\A (?<number>(\d{3})-?(\d{4})) \R
(?|
\d*? # rectus
(?|
\2 \3 \d*
[ ] (?<format> ABCDEFG ) [ ] (?<price>\d+)
|
(?=\3) \2 \d*
(?> [ ] [A-Z]+ [ ] \d+)*? # other formats until the good one
[ ] ( ABCABCD ) [ ] (\d+)
)
|
.* \R \d*? # inversus
(?|
\2 \3 \d*
[ ] ( GFEDCBA ) [ ] (\d+)
|
(?=\3) \2 \d*
(?> [ ] [A-Z]+ [ ] \d+)*?
[ ] ( DCBDCBA ) [ ] (\d+)
)
)
~x
EOD;
if (preg_match($pattern, $number . PHP_EOL . $suffix, $m))
echo 'number: ' . $m['number'] . PHP_EOL . 'format: ' . $m['format'] . PHP_EOL
. 'price: ' . $m['price'];
其他方法 (可能效果最佳)
特殊号码有限。您可以生成并使用包含所有特殊数字的多维数组,如下所示:
$speNum = [
'ABCDEFG' => [ '1234567', '2345678', '3456789' ],
'GFEDCBA' => [ '9876543', '8765432', '7654321' ],
'ABCABCD' => [ '1231234', '2342345' ...
];
$prices = [ 'ABCDEFG' => 10, 'ABCABCD' => 15, 'GFEDCBA' => 8 ...];
使用简单的foreach
,测试数字是否在数组中:
foreach ($speNum as $format => $nums) {
if (in_array($number, $nums)) {
echo 'number: ' . $number . PHP_EOL . 'format: ' . $format . PHP_EOL
. 'price: ' . $prices[$format];
break;
}
}
注意:对于第二种方法(为什么不是第一种方法),请先删除连字符。这种方法的主要优点是您可以轻松地将其扩展到其他类型的模式。请注意,您可以对数据库执行相同的操作。
答案 1 :(得分:1)
使用以下策略: 伪代码
String getPattern(String pn,int n)
{
int[] nums = new int[7];
for (int i = 0; i < 7; i++)
nums[i] = int.Parse(pn[i].ToString());
Array.Sort(nums);
String pat = pn;
Char chr = 'A';
for (int i = 0; i < 7; i++)
{
if (nums[i] != n)
{
pat = pat.Replace(nums[i].ToString(), chr.ToString());
if ((i + 1) < 7)
{
int shif = nums[i + 1] - nums[i];
chr = (Char)(Convert.ToUInt16(chr) + shif);
}
}
}
return pat;
}
它使用c#为我工作,它会自动检测输入数字的模式 你也可以将它发展得更高级(例如添加zyx模式检测)