求一算法

VCXIAOHEI 2012-03-22 02:52:56
源数据
A: 0、1
B: 0、1、2
C: 0、1、2、3
由ABC三组数据组合成(每组数据取其中1位,由A到C开始组合)

需求:
源数据 通过算法,找出与之匹配的目标数据(目标数据同源数据组合规律一致)
匹配规则:
1、源数据中的第A位数,目标数据中必须也有第A位数据;要匹配的数据为1
2、源数据中的第B位数,目标数据中必须也有第B位数据;要匹配的数据为0和1
3、源数据中的第C位数,目标数据中必须也有第C位数据;要匹配的数据为0和1

例:(源数据可以有剩余,但目标数据必须源数据由源数据全部匹配;前提:源数据一定会找出匹配目标数据的,这点不用考虑)
源数据为
100、101、101、011、002、020、023、123
目标数据为
100、101、003、012、020、121

得到的结果为
100 匹配100
101 匹配101
002 匹配003
001 匹配012
020 匹配020

想了两天了,也没想出来,望大能指导一二,先行谢谢了……

...全文
202 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
VCXIAOHEI 2012-03-27
  • 打赏
  • 举报
回复
其中把语句
1、if (rule.contains(s)) { 改成 if (matchKey(key, s)) {

2、if (i - k < min) { //规则不完全相同,则匹配规则最接近的
改成
if (i - k <= min) { //规则不完全相同,则匹配规则最接近的
VCXIAOHEI 2012-03-27
  • 打赏
  • 举报
回复


package com.boco.eoms.norm.bean;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class NormBeanTest {
public static void main(String[] args) throws Throwable {
String[] a = { "0", "1" };
String[] b = { "0", "1", "2" };
String[] c = { "0", "1", "2", "3" };
String[][] src = new String[][] { a, b, c };

Map map = getRules(src);
List rules = new ArrayList(map.entrySet());
// 按111(符合规则123),110(符合规则12),...000(不符合规则)的顺序,把符合规则的组合排序
Collections.sort(rules, new Comparator() {
public int compare(Object r1, Object r2) {
return ((String) ((Map.Entry) r2).getKey()).compareTo((String) ((Map.Entry) r1).getKey());
}
});

String[] srcData = { "111", "111", "101", "000", "101", "000" };
String[] tagData = { "121", "112", "112", "121" };
// String[] srcData = { "022", "100", "101", "002", "101", "020", "101", "111", "011" };
// String[] tagData = { "100", "101", "003", "012", "121", "012", "021", "023", "020" };

List srcList = new ArrayList(Arrays.asList(srcData));
boolean match = false;
List rule = null;
String key = null;
int min = 0;
int last = -1;
Outer: for (int index = 0; index < tagData.length; index++) {
String s = tagData[index];
min = rules.size() - 1;
last = -1;
for (int i = 0; i < rules.size(); i++) {
rule = (List) ((Map.Entry) rules.get(i)).getValue();
key = (String) ((Map.Entry) rules.get(i)).getKey();
if (matchKey(key, s)) {
for (int j = 0; j < srcList.size(); j++) {
String ss = (String) srcList.get(j);
if (rule.contains(ss)) {
match = true;
if (match) {
for (int k = 0; k < key.length(); k++) {
if (key.charAt(k) == '1') {
match &= (s.charAt(k) == ss.charAt(k));
}
}
}
if (match) {
for (int k = 0; k < i; k++) {
if (((List) ((Map.Entry) rules.get(k)).getValue()).contains(ss)) {
match = false;
if (i - k <= min) { //规则不完全相同,则匹配规则最接近的
min = i - k;
last = j;
}
break;
}
}
if (match) { //规则完全相同的匹配
System.out.println(ss + ":" + s);
srcList.remove(j);
continue Outer;
} else {
if (last == -1)
last = j;
}
}
}
}
}
}
if (last != -1) {
System.out.println(srcList.get(last) + ":" + s);
srcList.remove(last);
}
}
}

public static boolean matchKey(String key, String str) {
StringBuffer sb = new StringBuffer("");
for (int i = 0; i < str.length(); i++) {
if (i == 0) {
if (str.charAt(i) == '1') {
sb.append("1");
} else {
sb.append("0");
}
} else {
if (str.charAt(i) == '1' || str.charAt(i) == '0') {
sb.append("1");
} else {
sb.append("0");
}
}
}
String tmp = sb.toString();
StringBuffer sb2 = new StringBuffer("");
for (int i = 0; i < key.length(); i++) {
int a = Integer.parseInt(tmp.substring(i, i + 1)) & Integer.parseInt(key.substring(i, i + 1));
sb2.append(a);
}
String tmp2 = sb2.toString();
if (tmp.equals(tmp2)) {
return true;
} else {
return false;
}
}

/**
* 规则:
* 1、如果目标数据的第一位是1的话,源数据的第一位也必须是1
* 2、如果目标数据的第二位是0,源数据的第二位也必须是0;如果目标数据的第二位是1,源数据的第二位也必须是1
* 3、如果目标数据的第三位是0,源数据的第三位也必须是0;如果目标数据的第三位是1,源数据的第三位也必须是1
* 按111(符合规则123),110(符合规则12),...000(不符合规则)的顺序,把符合规则的组合排序
*/
public static Map getRules(String[][] src) {
String[] rule = { "1", "01", "01" };
int[] dig = new int[src.length];
int[] bit = new int[rule.length];
StringBuilder buf = new StringBuilder();
StringBuilder key = new StringBuilder();
Map map = new HashMap();
for (int i = 0; i < 8; i++) {
buf.delete(0, buf.length());
buf.append("000").append(Integer.toBinaryString(i));
map.put(buf.substring(buf.length() - 3), new ArrayList());
}
while (dig[0] < src[0].length) {
buf.delete(0, buf.length());
for (int i = 0; i < src.length; i++) {
buf.append(src[i][dig[i]]);
}

for (int i = 0, b = i; i < 8; i++, b = i) {
key.delete(0, key.length());
boolean match = true;
for (int j = bit.length - 1; j >= 0; j--) {
bit[j] = b % 2;
b >>= 1;
key.insert(0, bit[j]);

if (bit[j] == 1) {
match &= rule[j].contains(src[j][dig[j]]);
}
}
if (match) {
((List) map.get(key.toString())).add(buf.toString());
}
}

dig[dig.length - 1]++;
for (int i = dig.length - 1; i > 0; i--) {
if (dig[i] == src[i].length) {
dig[i] = 0;
dig[i - 1]++;
} else {
break;
}
}
}
return map;
}
}


这是我在 qybao 给的算法基础上改的,望 qybao 帮我分析一下,这样写能达到我要的效果不,自己拿些例子测试了一下,没有问题,但还是感觉有太踏实啊。
唐三角 2012-03-24
  • 打赏
  • 举报
回复
让我们暴力吧 让我们用遗传算法吧~~ :)

配对序列随机生成

评分标准 满足配对条件且配对的个数最终收敛到目标个数

然后 估计遗传个十几代就出来了。。
qybao 2012-03-24
  • 打赏
  • 举报
回复
想了一下,之前好像把问题复杂化了,其实就是求两个字符串的匹配规则的最大相似度
import java.util.*;
public class csdn {
public static void main(String[] args) throws Throwable {
String[] srcData = {"100", "101", "101", "011", "002", "020", "023", "123"};
String[] tagData = {"100", "101", "003", "012", "020", "121"};

List<String> srcList = new ArrayList<String>(Arrays.asList(srcData));

int max = 0, match = 0, idx = 0;
for (String s : tagData) {
max = -8;
for (int i=0; i<srcList.size(); i++) {
match = match(s, srcList.get(i));
if (match > max) {
max = match;
idx = i;
}
}
System.out.printf("%s:%s\n", srcList.get(idx), s);
srcList.add(srcList.remove(idx));
}
}

public static int match(String s1, String s2) {
String[] rule = {"1", "01", "01"};
int match = 0, m1 = 0, m2 = 0;
for (int i=0; i<rule.length; i++) {
if (rule[i].indexOf(s1.charAt(i)) >= 0) {
m1 = m1<<1 | 1;
} else {
m1 = m1<<1 | 0;
}

if (rule[i].indexOf(s2.charAt(i)) >= 0) {
m2 = m2<<1 | 1;
} else {
m2 = m2<<1 | 0;
}

if (rule[i].indexOf(s1.charAt(i)) >= 0 &&
rule[i].indexOf(s2.charAt(i)) >= 0) {
match <<= 1;
match |= (s1.charAt(i) == s2.charAt(i)) ? 1 : 0;
}
}

match -= Integer.bitCount(m1 ^ m2);
return match;
}
}
qybao 2012-03-24
  • 打赏
  • 举报
回复

import java.util.*;
public class Test {
public static void main(String[] args) throws Throwable {
String[] a = {"0", "1"};
String[] b = {"0", "1", "2"};
String[] c = {"0", "1", "2", "3"};
String[][] src = new String[][]{a, b, c};

Map<String, List<String>> map = getRules(src);
List<Map.Entry<String, List<String>>> rules = new ArrayList<Map.Entry<String, List<String>>>(map.entrySet());
Collections.sort(rules, new Comparator<Map.Entry<String, List<String>>>() {
public int compare(Map.Entry<String, List<String>> r1, Map.Entry<String, List<String>> r2) {
return r2.getKey().compareTo(r1.getKey());
}
}); //按111(符合规则123),110(符合规则12),...000(不符合规则)的顺序,把符合规则的组合排序

String[] srcData = {"100", "101", "101", "011", "002", "020", "023", "123"};
String[] tagData = {"100", "101", "003", "012", "020", "121"};

List<String> srcList = new ArrayList<String>(Arrays.asList(srcData));
boolean match = false;
List<String> rule = null;
String key = null;
int min = 7, last = -1;
Outer: for (String s : tagData) {
min = 7;
last = -1;
for (int i=0; i<rules.size()-1; i++) {
rule = rules.get(i).getValue();
key = rules.get(i).getKey();
if (rule.contains(s)) {
for (int j=0; j<srcList.size(); j++) {
String ss = srcList.get(j);
if (rule.contains(ss)) {
match = true;
for (int k=0; k<i; k++) {
if (rules.get(k).getValue().contains(ss)) {
match = false;
if (i-k < min) { //规则不完全相同,则匹配规则最接近的
min = i-k;
last = j;
}
break;
}
}
if (match) {
for (int k=0; k<key.length(); k++) {
if (key.charAt(k) == '1') {
match &= (s.charAt(k) == ss.charAt(k));
}
}
}
if (match) { //规则完全相同的匹配
System.out.printf("%s:%s\n", ss, s);
srcList.add(srcList.remove(j));
continue Outer;
} else {
if (last == -1) last = j;
}
}
}
}
}
if (last != -1) {
System.out.printf("%s:%s\n", srcList.get(last), s);
srcList.add(srcList.remove(last));
}
}
}

public static Map<String, List<String>> getRules(String[][] src) {
String[] rule = {"1", "01", "01"};
int[] dig = new int[src.length];
int[] bit = new int[rule.length];
StringBuilder buf = new StringBuilder();
StringBuilder key = new StringBuilder();
Map<String, List<String>> map = new HashMap<String, List<String>>();
for (int i=0; i<8; i++) {
buf.delete(0, buf.length());
buf.append("000").append(Integer.toBinaryString(i));
map.put(buf.substring(buf.length()-3), new ArrayList<String>());
}
while (dig[0] < src[0].length) {
buf.delete(0, buf.length());
for (int i=0; i<src.length; i++) {
buf.append(src[i][dig[i]]);
}

for (int i=0, b=i; i<8; i++, b=i) {
key.delete(0, key.length());
boolean match = true;
for (int j=bit.length-1; j>=0; j--) {
bit[j] = b%2;
b >>= 1;
key.insert(0, bit[j]);

if (bit[j] == 1) {
match &= rule[j].contains(src[j][dig[j]]);
}
}
if (match) {
map.get(key.toString()).add(buf.toString());
}
}

dig[dig.length-1]++;
for (int i=dig.length-1; i>0; i--) {
if (dig[i] == src[i].length) {
dig[i] = 0;
dig[i-1]++;
} else {
break;
}
}
}

return map;
}
}
qybao 2012-03-23
  • 打赏
  • 举报
回复
大概好像明白你的意思了
import java.util.*;
public class Test {
public static void main(String[] args) throws Throwable {
String[] a = {"0", "1"};
String[] b = {"0", "1", "2"};
String[] c = {"0", "1", "2", "3"};
String[][] src = new String[][]{a, b, c};

Map<String, List<String>> map = getRuleMap(src); //获取规则map

String[] srcData = {"100", "101", "101", "011", "002", "020", "023", "123"};
String[] tagData = {"100", "101", "003", "012", "020", "121"};

String[] rule = {"1", "01", "01"}; //规则定义
List<String> srcList = new ArrayList<String>(Arrays.asList(srcData));
//用一个链表把源数据匹配过的放到最后去匹配,也就是尽量匹配没使用过的源数据
StringBuilder key = new StringBuilder(); //规则组合的key
for (String s : tagData) {
key.delete(0, key.length());
for (int i=0; i<rule.length; i++) { //由目标数据推出规则组合key
if (rule[i].indexOf(s.charAt(i)) >= 0) {
key.append("1");
} else {
key.append("0");
}
}
List<String> ruleData = map.get(key.toString()); //取得规则key的规则字符串

for (int i=0; i<srcList.size(); i++) { //找出源数据规则相同的字符串
String ss = srcList.get(i);
if (ruleData.contains(s) && ruleData.contains(ss)) {
System.out.printf("%s:%s\n", ss, s);
srcList.add(srcList.remove(i));
break;
}
}
}
}

public static Map<String, List<String>> getRuleMap(String[][] src) {
int[] dig = new int[src.length];
String[] rule = {"1", "01", "01"}; //规则定义
StringBuilder buf = new StringBuilder(); //规则字符串
StringBuilder key = new StringBuilder(); //规则key
Map<String, List<String>> map = new HashMap<String, List<String>>();
while (dig[0] < src[0].length) {
buf.delete(0, buf.length());
for (int i=0; i<src.length; i++) {
buf.append(src[i][dig[i]]);
}

key.delete(0, key.length());
for (int i=0; i<rule.length; i++) {
//规则key,满足规则的标示为1,否则标示为0
//比如,同时满足规则1规则2规则3,则key为111,只满足规则1和规则2,key为110
//都不满足任何规则的则为000
if (rule[i].contains(src[i][dig[i]])) {
key.append("1");
} else {
key.append("0");
}
}

String k = key.toString();
if (! map.containsKey(k)) { //把规则字符串保存到相应的规则key对应的集合中
map.put(k, new ArrayList<String>());
}
map.get(k).add(buf.toString());

dig[dig.length-1]++;
for (int i=dig.length-1; i>0; i--) {
if (dig[i] == src[i].length) {
dig[i] = 0;
dig[i-1]++;
} else {
break;
}
}
}

return map;
}
}
VCXIAOHEI 2012-03-23
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 qybao 的回复:]
大概好像明白你的意思了
[/Quote]

还是不行啊
例如将源数据换一个数就不行了
String[] srcData = {"100", "101", "101", "111(原来为011)", "002", "020", "023", "123"};
String[] tagData = {"100", "101", "003", "012", "020", "121"};
应该是我描述的不好
1、如果目标数据的第一位是1的话,源数据的第一位也必须是1
2、如果目标数据的第二位是0,源数据的第二位也必须是0
如果目标数据的第二位是1,源数据的第二位也必须是1
3、如果目标数据的第三位是0,源数据的第三位也必须是0
如果目标数据的第三位是1,源数据的第三位也必须是1
特例:例如源数据100 即能满足目标数据002,也能满足目标数据010,还能满足目标数据102和120等等
可要将每个目标数据都有源数据匹配,就不太好分了
VCXIAOHEI 2012-03-22
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 qybao 的回复:]
没看明白LZ的匹配规则,大概思路,把所有组合放到每种规则中,然后在每种规则组合中判断源数据和目标数据是否存在
[/Quote]
你写的我看了一下,不满足我的这个规则啊……

匹配规则如下:
1、如果目标数据的第一位是1的话,源数据的第一位也必须是1
2、如果目标数据的第二位是0(或1),源数据的第二位也必须是0(或1)
3、如果目标数据的第三位是0(或1),源数据的第三位也必须是0(或1)

且每一个目标数据都要能找到源数据

ps:由于源数据可能适合目标数据1而且又适合目标数据2,所以就不知道分给哪个目标数据了,弄的我很迷糊啊
qybao 2012-03-22
  • 打赏
  • 举报
回复
没看明白LZ的匹配规则,大概思路,把所有组合放到每种规则中,然后在每种规则组合中判断源数据和目标数据是否存在
for example
import java.util.*;
public class Test {
public static void main(String[] args) throws Throwable {
String[] a = {"0", "1"};
String[] b = {"0", "1", "2"};
String[] c = {"0", "1", "2", "3"};
String[][] src = new String[][]{a, b, c};

Map<String, List<String>> rule = getRules(src); //获取组合规则

String[] srcData = {"100", "101", "101", "011", "002", "020", "023", "123"};
String[] tagData = {"100", "101", "003", "012", "020", "121"};
for (String s : tagData) {
boolean match = false;
String key = s.substring(0, 2); //规则1判断
if (rule.get(key).contains(s)) {
for (String ss : srcData) {
if (rule.get(key).contains(ss)) {
System.out.printf("%s:%s\n", ss, s);
match = true;
break;
}
}
}

if (match) continue;

key = s.substring(0, 1);//规则2判断
if (rule.get(key).contains(s)) {
for (String ss : srcData) {
if (rule.get(key).contains(ss)) {
System.out.printf("%s:%s\n", ss, s);
break;
}
}
}
}
}

public static Map<String, List<String>> getRules(String[][] src) {//获取所有组合规则
int[] dig = new int[src.length];
StringBuilder buf = new StringBuilder();
Map<String, List<String>> rule = new HashMap<String, List<String>>();
while (dig[0] < src[0].length) {
buf.delete(0, buf.length());
for (int i=0; i<src.length; i++) {
buf.append(src[i][dig[i]]);
}

String ruleKey = src[0][dig[0]];
if (! rule.containsKey(ruleKey)) {
rule.put(ruleKey, new ArrayList<String>());
}
rule.get(ruleKey).add(buf.toString());

ruleKey = buf.substring(0, 2);
if (! rule.containsKey(ruleKey)) {
rule.put(ruleKey, new ArrayList<String>());
}
rule.get(ruleKey).add(buf.toString());

dig[dig.length-1]++;
for (int i=dig.length-1; i>0; i--) {
if (dig[i] == src[i].length) {
dig[i] = 0;
dig[i-1]++;
} else {
break;
}
}
}

return rule;
}
}
VCXIAOHEI 2012-03-22
  • 打赏
  • 举报
回复
刚才发现有一处写错了,现更改过来,如下:::
源数据为
100、101、101、011、002、020、023、123
目标数据为
100、101、003、012、020、121

得到的结果为
100 匹配100
101 匹配101
002 匹配003
011 匹配012
020 匹配020
巫师 2012-03-22
  • 打赏
  • 举报
回复
数据挖掘?不懂呦~

13,100

社区成员

发帖
与我相关
我的任务
社区描述
Java J2ME
社区管理员
  • J2ME社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧