我有两个文件 一个叫 id.txt 信息大概是
12 Friend[14,15,19,46,57,79,20]
....
....有一个叫connected.txt 里面为
14 Connect[15,30,89]
15 Connect[14,19,57]
19 Connect[15,57,37,]
46 Connect[67,]
57 Connect[15,19,]
79 Connect[20,55,]
20 Connect[79,]
...
在connected.txt里面 14和15,30,89相连 那么15肯定也和14相连,30也跟15相连,89也跟15相连。我想要的是 读取id中的每一行 用户12 含有好友Friend[14,15,19,46,57,79,20] 这些好友之间的是否有互相连接的情况?情况又如何
对于用户12来说 他的好友
14 与15相连(30,89虽然也与14相连,但是不是12的好友)
15 与14,19,57相连
19 与15,57相连
46 都不相连,孤立
57 与15,19相连
79 与20相连
20 与79相连
如果画出图来 类似是:
57
/ |
19 —15 —14 79—20 46我想分别找出所有相连同的好友(并输出他们有多少个人连同) 以及孤立的好友
跪求代码 我只有100分了 都给了 如果嫌少 可以给人民币
12 Friend[14,15,19,46,57,79,20]
....
....有一个叫connected.txt 里面为
14 Connect[15,30,89]
15 Connect[14,19,57]
19 Connect[15,57,37,]
46 Connect[67,]
57 Connect[15,19,]
79 Connect[20,55,]
20 Connect[79,]
...
在connected.txt里面 14和15,30,89相连 那么15肯定也和14相连,30也跟15相连,89也跟15相连。我想要的是 读取id中的每一行 用户12 含有好友Friend[14,15,19,46,57,79,20] 这些好友之间的是否有互相连接的情况?情况又如何
对于用户12来说 他的好友
14 与15相连(30,89虽然也与14相连,但是不是12的好友)
15 与14,19,57相连
19 与15,57相连
46 都不相连,孤立
57 与15,19相连
79 与20相连
20 与79相连
如果画出图来 类似是:
57
/ |
19 —15 —14 79—20 46我想分别找出所有相连同的好友(并输出他们有多少个人连同) 以及孤立的好友
跪求代码 我只有100分了 都给了 如果嫌少 可以给人民币
46 都不相连,孤立
================================================
没明白================================================
可以实现的,只是解释起来有点麻烦,如果格式可以变一下的话,变成一个xml或配置文件什么的,解释起来会更方便
import java.io.FileReader;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;public class Test { @SuppressWarnings("rawtypes")
public static void main(String[] args) throws Exception {
FileReader fr = new FileReader("d://id.txt");
BufferedReader br = new BufferedReader(fr);
String line = null;
Map<String,Set> idmap = new HashMap<String,Set>();
while ((line = br.readLine()) != null) {
String[] idarray = line.split(" ");
String id = idarray[0];
Set<String> set = new HashSet<String>();
String friends = line.substring(line.indexOf("[") + 1,line.lastIndexOf("]"));
String[] friendarray = friends.split(",");
for(String friend : friendarray){
set.add(friend);
}
idmap.put(id, set);
}
FileReader fr1 = new FileReader("d://connected.txt");
BufferedReader br1 = new BufferedReader(fr1);
String line1 = null;
while ((line1 = br1.readLine()) != null) {
String[] conarray = line1.split(" ");
String conid = conarray[0];
String friends = line1.substring(line1.indexOf("[") + 1,line1.lastIndexOf("]"));
String[] friendarray = friends.split(",");
StringBuffer buf = new StringBuffer();
String id = null;
boolean flag = false;
for(String key : idmap.keySet()){
if(idmap.get(key).contains(conid)){
for(String friend : friendarray){
if(!idmap.get(key).contains(friend)){
friends = friends.replaceAll(",?" + friend + ",?", "");
buf.append(friend);
buf.append(",");
}else{
flag = true;
}
}
id = key;
break;
}
}
if(flag && friendarray.length > 0){
System.out.print(conid + "与" + friends + "相连 ");
}else{
System.out.print(conid + "都不相连,孤立 ");
}
if(buf.length() > 0){
System.out.print("(" + buf + "虽然也与" + conid + "相连" + "但是不是" + id + "的好友)");
}
System.out.println();
}
br.close();
br1.close();
}}
意思是对于用户12来说 他的好友[14,15,19,46,57,79,20]
46与其他的14,15,19,57,79,20都不相连 尽管他与67相连 但67不在12的好友列表里面在xml当然容易 但是悲剧的是现在这些都存在.txt里面 其实数据库检索会很方便 但是老师并没让用
我要找到的是所有相连同的好友(并输出他们有多少个人连同) 以及孤立的好友所以最后希望输出是
12 相连[57,19,15,14]相连[79,20]孤立[46]您看能不能给改改另外我的数据connected.txt比较大 大约300M左右 如果两个for循环会不会很慢?
按照常规理解,既然id.txt里面已经是 联系信息:
12 Friend[14,15,19,46,57,79,20]
为啥还要再来个connected.txt来说明朋友之间的关系?
14 Connect[15,30,89]
直接用id.txt中的朋友关系来计算不就已经足够了?
换句话说,如果 connected.txt 有关于 12 的说明,是不是也是:
12 Connect[14,15,19,46,57,79,20]
上次的我是根据ldh911 的改的 所以您的根本没有用 但是您也给提供了 所以就给分了 这样也要说我。
package net.csdn.bbs.mrsworf;import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;public class FindConnected { static class Task{
Integer id;//待查找的ID,用例是12.
HashSet<Integer> friends = new HashSet<Integer>();//ID的friends,用例是[14,15,19,46,57,79,20]
HashSet<Integer> finds = new HashSet<Integer>();//待查找的friends
ArrayList<HashSet<Integer>> connects = new ArrayList<HashSet<Integer>>();//连通域
HashSet<Integer> alones = new HashSet<Integer>();//孤立节点
public Task(Integer id) {
super();
this.id = id;
}
}
interface ConnectedFinder{
void findConnect(File idFile,File connectFile,File targetFile)throws IOException, IllegalAccessException;
}
static class EasyConnectedFinder implements ConnectedFinder{ private boolean ignoreWrongFormat = true;//是否忽略List文件中数据的格式错误
private int readSize = 5000;
class ConnectFileReader{
private BufferedReader reader;
private int lineNumber;
public ConnectFileReader(File connectFile) throws FileNotFoundException {
reader = new BufferedReader(new FileReader(connectFile));lineNumber=1;
}
public HashMap<Integer,HashSet<Integer>> readConnect(int num) throws IOException, IllegalAccessException{
String line = null;
HashMap<Integer,HashSet<Integer>> connects = new HashMap<Integer, HashSet<Integer>>();
for(int i=0;i<num && (line=reader.readLine())!=null;i++,lineNumber++){
int index = line.indexOf(' ')>0?line.indexOf(' '):line.indexOf('\t');
if(index<0)throw new IllegalAccessException("数据格式不正确,id后面没有空格符,行号:"+lineNumber);
Integer id = new Integer(line.substring(0,index).trim());
index = line.indexOf('[');//创建一个行级索引,辅助数据解析。
int index_ = line.lastIndexOf(']');//创建另一个行级索引,辅助数据解析。
if(index<0){
if(ignoreWrongFormat)continue;//是否忽略List文件中数据的格式错误,如果不忽略则抛出异常,中断执行。
else throw new IllegalAccessException("数据格式不正确,没找到'['字符:"+line);
}
if(index_<0){
if(ignoreWrongFormat)continue;//是否忽略List文件中数据的格式错误,如果不忽略则抛出异常,中断执行。
else throw new IllegalAccessException("数据格式不正确,没找到']'字符:"+line);
}
String allFriends = line.substring(index+1,index_);//所有的friend_id,以逗号分开。
String friends [] = allFriends.split("\\,|\\,");//以逗号为分隔符,拆分字符串
HashSet<Integer> set = new HashSet<Integer>();
connects.put(id, set);
for(int j=0;i<friends.length;j++){
if(friends[j].trim().length()>0){
set.add(new Integer(friends[j].trim()));
}
}
}
return connects;
}
public void close() throws IOException{
reader.close();
}
}
public void findConnect(File idFile, File connectFile, File targetFile)
throws IOException, IllegalAccessException {
if(targetFile!=null)targetFile.delete();
BufferedReader idReader = new BufferedReader(new FileReader(idFile));
ConnectFileReader cfReader = new ConnectFileReader(connectFile);
BufferedWriter writer = new BufferedWriter(new FileWriter(targetFile));
try{
HashMap<Integer,HashSet<Integer>> cache = cfReader.readConnect(readSize);
ArrayList<Task> tasks = new ArrayList<Task>();
Task task = null;
for(int lineNumber=1;(task=readeOneTask(idReader,lineNumber))!=null;lineNumber++){
boolean matchOver = findCnnect(task,cache);
if(matchOver){
write2Target(task,writer);
}else{
tasks.add(task);
}
}
while((cache=cfReader.readConnect(readSize)).size()>0){
for(Iterator<Task>iter = tasks.iterator();iter.hasNext();){
Task t = iter.next();
if(findCnnect(t,cache)){
iter.remove();
write2Target(t,writer);
}
}
}
for(Task t : tasks){
t.alones.addAll(t.finds);
write2Target(t,writer);
}
}finally{
try { idReader.close(); } catch (Exception e) {}
try { cfReader.close(); } catch (Exception e) {}
try { writer.close(); } catch (Exception e) {}
}
}
private void write2Target(Task task, BufferedWriter writer) throws IOException {
writer.write(task.id);writer.write(' ');
for(HashSet<Integer> set : task.connects){
writer.write("相连[");
int c = 0;
for(Integer cid : set){
if(c++>0)writer.write(',');
writer.write(cid);
}
writer.write(']');
}
if(task.alones.size()>0){
writer.write("孤立[");
int c = 0;
for(Integer aid : task.alones){
if(c++>0)writer.write(',');
writer.write(aid);
}
writer.write(']');
}
writer.newLine();
} /**
* 该方法在细节上可能产生bug,没有处理两个连通域如果有相同元素时合并的问题。
*/
private boolean findCnnect(Task task, HashMap<Integer, HashSet<Integer>> cache) {
for(Iterator<Integer>iter = task.finds.iterator();iter.hasNext();){
Integer fid = iter.next();
HashSet<Integer> conns = cache.get(fid);
if(conns!=null){
for(Integer con : conns){
if(task.friends.contains(con)){
boolean find = false;
for(HashSet<Integer> area : task.connects){
if(area.contains(con)){
area.add(fid);
find = true;
break;
}
}
if(!find){
HashSet<Integer> area = new HashSet<Integer>();
area.add(fid);
task.connects.add(area);
}
iter.remove();
}
}
}
}
return false;
} private Task readeOneTask(BufferedReader reader,int lineNumber)throws IOException, IllegalAccessException{
String line = reader.readLine();
if(line==null)return null;
int index = line.indexOf(' ')>0?line.indexOf(' '):line.indexOf('\t');
if(index<0)throw new IllegalAccessException("数据格式不正确,id后面没有空格符,行号:"+lineNumber);
Integer id = new Integer(line.substring(0,index).trim());
Task task = new Task(id);
index = line.indexOf('[');//创建一个行级索引,辅助数据解析。
int index_ = line.lastIndexOf(']');//创建另一个行级索引,辅助数据解析。
if(index<0 && !ignoreWrongFormat){
throw new IllegalAccessException("数据格式不正确,没找到'['字符:"+line);
}
if(index_<0 && !ignoreWrongFormat){
throw new IllegalAccessException("数据格式不正确,没找到']'字符:"+line);
}
String allFriends = line.substring(index+1,index_);//所有的friend_id,以逗号分开。
String friends [] = allFriends.split("\\,|\\,");//以逗号为分隔符,拆分字符串
for(String friend:friends){
if(friend.trim().length()>0){
task.friends.add(new Integer(friend.trim()));
}
}
task.finds.addAll(task.friends);
return task;
}
} /**
* 测试用例
*/
public static void main(String[] args) {
final String IdFile = "id.txt";
final String connectFile = "connected.txt";
final String TargetFile = "results.txt";
ConnectedFinder finder = new EasyConnectedFinder();
try {
finder.findConnect(new File(IdFile),new File(connectFile),new File(TargetFile));
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} }}
跟之前你帖子里面贴的数据结构貌似又不一样了,看得我眼花缭乱、头晕目眩啊其实用递归不合适,应该用迭代就行了。
每次迭代都负责将一个新的待处理组增加到已处理好的分组中来,伪代码如下:List<Set> groups; // 记录最终处理的结果。
迭代读取下一个处理组:int[] newGroup; 比如:[13,14,21] {
/* 先将新的处理组,完整加入组中 */
Set newSet = new HashSet();
newSet.addAll(newGroup);
groups.add(newSet); /* 对新加入的组,逐个分析其与原有组的关系,按需进行合并 */
for (num : newGroup) { // 循环每个新元素
while (pos < groups.size()) { // 循环分析每个组
Set joinGroup = null;
int pos = 0;
Set g = groups.get(pos);
if (g.contains(num)) { // 检查组中是否有该元素
if (joinGroup != null) { // 之前已经有组包含了,意味着要合并组
joinGroup.addAll(g); // 全部加入之前的组
groups.remove(g); // 该组删除掉
continue; // 继续下一个循环(不累加pos)
} else { // 之前没有组已经包含过该元素
joinGroup = g; // 记录该组,以便后续合并之需
}
}
pos++;
}
}
}