package Bbstree;import java.io.*;
import java.util.HashMap;
import java.util.Map;
public class Tree { TreeNode trnode[];
public static void main(String[] args) {
// TODO Auto-generated method stub
String allword=null,buffword; //保存单个单词
String sentense[]=null;//读取整个字符串,tree用来实现二叉树
int length,a,dep=0;
TreeNode tnodebuf,thead;
try
{
String encoding="UTF-8";
File file = new File("D://test_2.txt");    //file 指向目录中的文件
if(file.isFile() && file.exists())
{ //判断文件是否存在
           InputStreamReader read = new InputStreamReader(new FileInputStream(file),encoding);//考虑到汉子编码格式           
           BufferedReader br =new BufferedReader(read);        
           allword=br.readLine();    //读取文件中的一行数据
           length=allword.length();    //获得字符串s1的长度并赋值给length_1
           read.close();
}

else{
   System.out.println("找不到指定的文件");
}
}
catch(Exception e){
System.out.println("读取文件内容出错");
e.printStackTrace();
}
if(allword!=null)
{
sentense=allword.split(" ");
}
TreeNode trnode[]=new TreeNode[sentense.length];
for(int i=0;i<sentense.length;i++)
{
trnode[i]=new TreeNode(sentense[i]);

}
for(int i=0;i<sentense.length;i++)
for(int j=0;j<sentense.length-i-1;j++)
{
if(trnode[j].length>trnode[j+1].length)
{
tnodebuf=new TreeNode(sentense[i]);
tnodebuf.NodeCopy(trnode[j]);
trnode[j].NodeCopy(trnode[j+1]);
trnode[j+1].NodeCopy(tnodebuf);
}
}
thead=new TreeNode();
thead.pos=(0+sentense.length)/2;
int depth=Creatbtree(trnode,0,sentense.length-1,0,sentense.length,dep);
TreeNode netree[]=new TreeNode[sentense.length];
for(int i=0;i<sentense.length;i++)
{
netree[i]=new TreeNode();
}
int nelength=FindAcctimes(trnode,netree,sentense.length);
wordsort(netree,nelength-1);
fiwrite(netree,depth,nelength-1);
}
//trnode保存二叉树,netree保存出现次数,以及去除了相同的字符串
private static int Creatbtree(TreeNode trnode[],int pos1,int pos2,int i,int length,int dep)
{ //递归简历平衡排序二叉树
int dep1,dep2;
dep++;

if(pos1<=pos2)
{
if(pos1==pos2)
{
trnode[(pos1+pos2)/2].lchild=-1;
trnode[(pos1+pos2)/2].rchild=-1;
trnode[(pos1+pos2)/2].pos=dep;
}
else if((pos1+pos2)/2==pos1)
{
trnode[(pos1+pos2)/2].lchild=-1;
trnode[(pos1+pos2)/2].rchild=(pos2+(pos1+pos2)/2+1)/2;
trnode[(pos1+pos2)/2].pos=dep;
}
else
{
trnode[(pos1+pos2)/2].lchild=(pos1+(pos1+pos2)/2-1)/2;
trnode[(pos1+pos2)/2].rchild=(pos2+(pos1+pos2)/2+1)/2;
trnode[(pos1+pos2)/2].pos=dep;
}

dep1=Creatbtree(trnode,pos1,(pos1+pos2)/2-1,i,length,dep);
dep2=Creatbtree(trnode,(pos1+pos2)/2+1,pos2,i,length,dep);
dep=((dep1>dep2)?dep1:dep2)>dep?((dep1>dep2)?dep1:dep2):dep;//得出深度


}
return dep;
}
private static int FindAcctimes(TreeNode trnode[],TreeNode treenode[],int length)
{
//找出每个单词出现次数并去除同样字符串

int tnum=0,relength=length;
Map<String, String> existMap = new HashMap<String, String>();
for(int i=0;i<length;i++)//将数据存入一个数组,有相同字符串ACCTIMES就+1
{

if(existMap.get(trnode[i].treenode)==null)//字符串不存在
 {
 existMap.put(trnode[i].treenode,Integer.toString(trnode[i].acctimes));
 treenode[tnum].NodeCopy(trnode[i]);
tnum++;
 }
else if(existMap.get(trnode[i].treenode)!=null)//字符串已存在
{
existMap.put(trnode[i].treenode,Integer.toString(trnode[i].acctimes+1));
relength--;
}
}
for(int i=0;i<length;i++)
{//存入出现次数
try
{
treenode[i].acctimes=Integer.valueOf(existMap.get(treenode[i].treenode)).intValue();
}
catch(Exception e){}
}
return length;
 
}
private static void fiwrite(TreeNode trnode[],int dep,int length)
{
try
{
File file = new File("D://test_1.txt");
FileWriter fw_clear = new FileWriter(file);
BufferedWriter bw_clear = new BufferedWriter(fw_clear);
bw_clear.write("");
bw_clear.close();
}
catch(Exception e){}
try
{
File file = new File("D://test_1.txt");
FileWriter fw = new FileWriter(file,true);
BufferedWriter bw = new BufferedWriter(fw);
bw.write("深度为:"+dep);
bw.newLine();
for(int i=0;i<length-1;i++)
bw.write(trnode[i].treenode+":"+trnode[i].acctimes+";   ");
bw.close();
}
catch(Exception e){}
}
private static void wordsort(TreeNode treenode[],int length)
{
TreeNode bufnode=new TreeNode();
for(int i=0;i<length-1;i++)
for(int j=0;j<length-i-2;j++)
{
if(treenode[j].treenode.codePointAt(0)>treenode[j+1].treenode.codePointAt(0))
{
bufnode=new TreeNode();
bufnode.NodeCopy(treenode[j]);
treenode[j].NodeCopy(treenode[j+1]);
treenode[j+1].NodeCopy(bufnode);
}
}
}
}Exception in thread "main" java.lang.NullPointerException
at Bbstree.Tree.wordsort(Tree.java:166)
at Bbstree.Tree.main(Tree.java:66)如果我自己从网页中复制东西粘贴的txt中,程序运行正常,但是要是在txt中进行操作,比如加进空格字符什么的,就会这样报错。
javatxt

解决方案 »

  1.   

     if(treenode[j].treenode.codePointAt(0)>treenode[j+1].treenode.codePointAt(0)) 
    这一行报错空指针么?
    那你就把这一行的内容每个都输出一遍,看看到底哪个为空
    个人感觉,应该是treenode[j+1]为空
      

  2.   

    既然报错说at Bbstree.Tree.wordsort(Tree.java:166)有空指针,那你就有debug看看那个对象为null了还在调用其属性或者方法撒。然后分析为啥会出现这样的数据。
      

  3.   

    但是如果是其他地方copy一个英文句子粘贴进去就不会报错
      

  4.   

    这个算法应该没有问题,我觉得问题出在字符集上可能,因为如果是其他地方copy一个英文句子粘贴进去就不会报错
      

  5.   

    应该是编码的问题、、网页上应该是utf-8的而windows默认的是gbk、楼主可以试试我个人觉得应该是 这个问题
      

  6.   


    把test_2.txt改成UTF-8格式保存或者把程序中的encoding改成GBK。
      

  7.   


    把test_2.txt改成UTF-8格式保存或者把程序中的encoding改成GBK。
    没有用 
    如下报错Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0
    at java.lang.String.codePointAt(Unknown Source)
    at Bbstree.Tree.wordsort(Tree.java:168)
    at Bbstree.Tree.main(Tree.java:67)我的txt文本是这样的 i am a student is pig is pig gos nit
    在里面接着输入之前没有出现过的单词,程序可以继续运行,但是输入的单词有重复就会这样报错,比如这样i am a student is pig is pig gos nit hehe ni cai wo sh ni  cai
      

  8.   


    把test_2.txt改成UTF-8格式保存或者把程序中的encoding改成GBK。
    没有用 
    如下报错Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0
    at java.lang.String.codePointAt(Unknown Source)
    at Bbstree.Tree.wordsort(Tree.java:168)
    at Bbstree.Tree.main(Tree.java:67)我的txt文本是这样的 i am a student is pig is pig gos nit
    在里面接着输入之前没有出现过的单词,程序可以继续运行,但是输入的单词有重复就会这样报错,比如这样i am a student is pig is pig gos nit hehe ni cai wo sh ni  cai你的TreeNode介意发出来吗?我本地跑一下。
      

  9.   


    把test_2.txt改成UTF-8格式保存或者把程序中的encoding改成GBK。
    没有用 
    如下报错Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0
    at java.lang.String.codePointAt(Unknown Source)
    at Bbstree.Tree.wordsort(Tree.java:168)
    at Bbstree.Tree.main(Tree.java:67)我的txt文本是这样的 i am a student is pig is pig gos nit
    在里面接着输入之前没有出现过的单词,程序可以继续运行,但是输入的单词有重复就会这样报错,比如这样i am a student is pig is pig gos nit hehe ni cai wo sh ni  cai你的TreeNode介意发出来吗?我本地跑一下。
    package Bbstree;
    public class TreeNode {
    public int pos=0,length;
    public int acctimes=0;
    public String treenode;
    public int lchild=0,rchild=0;
    public TreeNode(String aword)//构造函数
    {
    this.treenode=aword;
    this.length=treenode.length();
    this.lchild=0;
    this.rchild=0;
    this.pos=0;
    this.acctimes=1;

    }
    public TreeNode()//构造函数
    {
    this.length=0;
    this.lchild=0;
    this.rchild=0;
    this.pos=0;
    this.acctimes=1;
    this.treenode=null; }
    public int NodeAcctime(String[] aword)//每个单词的出现次数
    {
    for(int i=0;i<aword.length;i++)
    {
    if(aword[i]==treenode)
    acctimes++;
    }
    return acctimes; }
    public void NodeCopy(TreeNode tNode)//交换两个节点的值
    {
    this.length=tNode.length;
    this.lchild=tNode.lchild;
    this.rchild=tNode.rchild;
    this.pos=tNode.pos;
    this.acctimes=tNode.acctimes;
    this.treenode=tNode.treenode;
    }
    }
    就是这个样子的  麻烦了哈!
      

  10.   


    把test_2.txt改成UTF-8格式保存或者把程序中的encoding改成GBK。
    没有用 
    如下报错Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0
    at java.lang.String.codePointAt(Unknown Source)
    at Bbstree.Tree.wordsort(Tree.java:168)
    at Bbstree.Tree.main(Tree.java:67)我的txt文本是这样的 i am a student is pig is pig gos nit
    在里面接着输入之前没有出现过的单词,程序可以继续运行,但是输入的单词有重复就会这样报错,比如这样i am a student is pig is pig gos nit hehe ni cai wo sh ni  cai你的TreeNode介意发出来吗?我本地跑一下。
    package Bbstree;
    public class TreeNode {
    public int pos=0,length;
    public int acctimes=0;
    public String treenode;
    public int lchild=0,rchild=0;
    public TreeNode(String aword)//构造函数
    {
    this.treenode=aword;
    this.length=treenode.length();
    this.lchild=0;
    this.rchild=0;
    this.pos=0;
    this.acctimes=1;

    }
    public TreeNode()//构造函数
    {
    this.length=0;
    this.lchild=0;
    this.rchild=0;
    this.pos=0;
    this.acctimes=1;
    this.treenode=null; }
    public int NodeAcctime(String[] aword)//每个单词的出现次数
    {
    for(int i=0;i<aword.length;i++)
    {
    if(aword[i]==treenode)
    acctimes++;
    }
    return acctimes; }
    public void NodeCopy(TreeNode tNode)//交换两个节点的值
    {
    this.length=tNode.length;
    this.lchild=tNode.lchild;
    this.rchild=tNode.rchild;
    this.pos=tNode.pos;
    this.acctimes=tNode.acctimes;
    this.treenode=tNode.treenode;
    }
    }
    就是这个样子的  麻烦了哈!测试了一下,主要是"i am a student is pig is pig gos nit hehe ni cai wo sh ni  cai", ni和cai之间多了个空格,所以导致有""空字符串出现,
    而你的FindAcctimes方法中:if(existMap.get(trnode[i].treenode)==null)//字符串不存在
    对字符串的判断只判断null,没有判断空。
    所以导致在wordsort的treenode[j].treenode.codePointAt(0)会报StringIndexOutOfBoundsException异常。
      

  11.   

    上面的说法有点问题,重新发一下:
    测试了一下,主要是"i am a student is pig is pig gos nit hehe ni cai wo sh ni  cai", ni和cai之间多了个空格,所以导致有""空字符串出现,导致在wordsort的treenode[j].treenode.codePointAt(0)会报StringIndexOutOfBoundsException异常。所以如果你需要对空字符串""也要排序的话,先要判断一下作另外的处理。或者你想要出现多个空格当一个空格进行分隔的,可以使用正则表达式,如:allword.split("\\s+");
      

  12.   

    你读的时候用指定编码集的方式读试试,也就是
    InputStreamReader ir = new InputStreamReader(in, "utf-8");也可以指定是你的是window系统的话字符集默认是gbk的所有你用“UTF_8”读出来试试,这样可以理解吧?