因业务需求需要做一个文字对比的功能,在原文中标出错误的地方。网上找了好久,多就是通过分词挑出两个内容中的不同。于是自己写了一个简单工具类,新手代码不是很规则,不懂算法就自己的想法写的,各位大神勿喷,多多指导。
效果图如下
image.png
下面上代码:
public class ResultUtils {
private static List<WordBean> origlist;
private static List<String> tarList;
private static List<WordBean> errorList;
private static List<String> pinOrigList;
/**
* 获取背诵,原文中那些字背错了
*
* @param original
* 原文
* @param reciteText
* 背诵的内容
* @return
*/
public static List<WordBean> getError(String original, String reciteText) {
init();
handleText(original, reciteText);
return dispose();
}
/**
* 初始化某些集合
*/
private static void init() {
origlist = new ArrayList<WordBean>();
tarList = new ArrayList<String>();
errorList = new ArrayList<WordBean>();
pinOrigList = new ArrayList<String>();
}
/**
* 字符串处理
*
* @param original
* @param reciteText
*/
private static void handleText(String original, String target) {
// 去除原文和背诵内容中的特殊字符(注:先去掉标点之后再考虑标点问题)
// original = replaceSpecStr(original);
target = replaceSpecStr(target);
// 去除 背诵内容中的数字
// target = target.replaceAll("\\d+", "");
// 原文进行单字拆分放入集合
for (int i = 0; i < original.length(); i++) {
// 单个文字拆分
String str = replaceSpecStr(String.valueOf(original.charAt(i)));
// 对非空文字进行保存
if (str != null && !"".equals(str)) {
// 生成对象并保存
WordBean wBean = new WordBean();
wBean.setOraIndex(i);
wBean.setWord(str);
origlist.add(wBean);
pinOrigList.add(str);
}
}
// 对背诵内容进行筛选,把原文中存在的字符挑出来
for (int i = 0; i < target.length(); i++) {
String str = String.valueOf(target.charAt(i));
// 转成拼音进行判断
// 原文集合中存在的文字加入到集合
if (pinOrigList.contains(str)) {
tarList.add(str);
}
}
// 原文和背诵内容进行对比,确定原文中文字在背诵内容中的位置
for (WordBean bean : origlist) {
for (int i = 0; i < tarList.size(); i++) {
// 文字相同,确定位置
if (bean.getWord().equals(tarList.get(i))) {
bean.addLocation(i);
}
}
}
}
/**
* 对两个集合进行处理
*/
private static List<WordBean> dispose() {
// 挑出对应位置为空的对象
for (WordBean wordBean : origlist) {
if (wordBean.getTarIndexs() == null) {
errorList.add(wordBean);
}
}
// 移除位置为空的对象
origlist.removeAll(errorList);
// 多个对应位置的对象集合
List<WordBean> list = getRepetitionWord();
// 移除多个对象的
origlist.removeAll(list);
// 文字重复的对象集合
List<WordBean> sriglist = getSingleRepetition(origlist);
// 移除单个重复对象
origlist.removeAll(sriglist);
// 处理剩余单个集合
disposeOne(origlist);
for (WordBean wordBean : list) {
origlist.add(wordBean);
sort(origlist);
disposeMore(wordBean, origlist);
}
for (WordBean wordBean : sriglist) {
origlist.add(wordBean);
sort(origlist);
disposeMore(wordBean, origlist);
}
origlist.addAll(errorList);
sort(origlist);
return origlist;
}
/**
* 挑出原文中汉字中,对应位置较多的文字 因为汉字重复所以会产生多个位置
*
* @return
*/
private static List<WordBean> getRepetitionWord() {
List<WordBean> beans = new ArrayList<WordBean>();
for (WordBean bean : origlist) {
if (bean.getTarIndexs() != null && bean.getTarIndexs().size() > 1) {
beans.add(bean);
}
}
return beans;
}
/**
* 挑出原文中重复的文字
*
* @param list
* @return
*/
private static List<WordBean> getSingleRepetition(List<WordBean> list) {
List<WordBean> beans = new ArrayList<WordBean>();
for (WordBean bean : list) {
for (WordBean wBean : list) {
if (bean != wBean && !beans.contains(bean)
&& bean.getWord().equals(wBean.getWord())) {
beans.add(bean);
}
}
}
return beans;
}
/**
* 对集合中有一个对应位置的文字进行判断处理
*
* @param copy
*/
private static void disposeOne(List<WordBean> copy) {
for (int i = 0; i <= copy.size() - 1; i++) {
WordBean bean = copy.get(i);
if (bean.getTarIndexs() == null) {
// 当前对象的对应位置为空,结束本层循环
continue;
}
// 获取下一个对象
WordBean nextBean = getNext(bean, copy);
if (nextBean == null) {
continue;
}
// 位置对应关系,如果当前对象对应位置大于下一个对象的对应位置,当前对象位置不合理置空
if (bean.getTarIndexs().get(0) > nextBean.getTarIndexs().get(0)) {
bean.setTarIndexs(null);
disposeOne(copy);
}
}
}
/**
* 对存在多个对应位置的对象进行处理
*
* @param bean
* @param list
*/
private static void disposeMore(WordBean bean, List<WordBean> list) {
// System.err.println(bean.toString());
int position = list.indexOf(bean);
// 如果当前对象是对一个对象
// 判断标记,是否存在合适位置
boolean isEnd = false;
if (position == 0) {
// 获取下一个对象
WordBean next = getNext(bean, list);
// 对位置进行遍历判断
for (Integer in : bean.getTarIndexs()) {
// 位置关系是当前对应位置小于下一个对象的对应位置
if (next != null && in < next.getTarIndexs().get(0)) {
// 满足关系对对象进行保存,结束循环
List<Integer> integers = new ArrayList<Integer>();
integers.add(in);
bean.setTarIndexs(integers);
isEnd = true;
break;
}
}
} else if (position == list.size()) {
// 如果当前位置是最后一个
WordBean lastBean = getLast(bean, list);
// 对位置进行遍历判断
for (Integer in : bean.getTarIndexs()) {
// 位置关系是当前对应位置大于上一个对象的对应位置
if (lastBean != null && in > lastBean.getTarIndexs().get(0)) {
// 满足关系对对象进行保存,结束循环
List<Integer> integers = new ArrayList<Integer>();
integers.add(in);
bean.setTarIndexs(integers);
isEnd = true;
break;
}
}
} else {
// 当前位置是中间位置
WordBean lastBean = getLast(bean, list);
WordBean nextBean = getNext(bean, list);
// 遍历对应位置
for (Integer in : bean.getTarIndexs()) {
// 位置对应关系,大于上一个,小于下一个
if (lastBean != null && nextBean != null
&& in > lastBean.getTarIndexs().get(0)
&& in < nextBean.getTarIndexs().get(0)) {
// 满足关系对对象进行保存,结束循环
List<Integer> integers = new ArrayList<Integer>();
integers.add(in);
bean.setTarIndexs(integers);
isEnd = true;
break;
}
}
}
// 没有合适的位置对应。置空
if (!isEnd) {
bean.setTarIndexs(null);
}
}
/**
* 获取当前文字对象,上一个有对应位置的对象
*
* @param bean
* @param list
* @return
*/
private static WordBean getLast(WordBean bean, List<WordBean> list) {
int index = list.indexOf(bean);
WordBean rsultBean = null;
for (int i = index - 1; i >= 0; i--) {
if (list.get(i).getTarIndexs() != null) {
rsultBean = list.get(i);
break;
}
}
return rsultBean;
}
/**
* 获取当前文字对象,下一个有对应位置的对象
*
* @param wordBean
* @param wBeans
* @return
*/
private static WordBean getNext(WordBean wordBean, List<WordBean> wBeans) {
WordBean bean = null;
int dex = wBeans.indexOf(wordBean);
for (int i = dex + 1; i < wBeans.size(); i++) {
if (wBeans.get(i).getTarIndexs() != null) {
bean = wBeans.get(i);
break;
}
}
return bean;
}
/**
* 集合排序,根据在原文中的位置进行排序
*
* @param list
*/
private static void sort(List<WordBean> list) {
Collections.sort(list, new Comparator<WordBean>() {
public int compare(WordBean arg0, WordBean arg1) {
if (arg0.getOraIndex() < arg1.getOraIndex()) {
return -1;
} else if (arg0.getOraIndex() > arg1.getOraIndex()) {
return 1;
}
return 0;
}
});
}
/**
* 正则替换所有特殊字符
*
* @param orgStr
* @return
*/
private static String replaceSpecStr(String orgStr) {
if (null != orgStr && !"".equals(orgStr.trim())) {
String regEx = "[\\s~·`!!@#¥$%^……&*(())\\-——\\-_=+【\\[\\]】{{}}\\|、\\\\;;::‘'“”\",,《<。.》>、/??\n]";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(orgStr);
return m.replaceAll("");
}
return null;
}
}
bean对象代码
public class WordBean implements Serializable{
private String word;
private List<Integer> tarIndexs;
private int oraIndex;
public String getWord() {
return word;
}
public void setWord(String word) {
this.word = word;
}
public List<Integer> getTarIndexs() {
return tarIndexs;
}
public void setTarIndexs(List<Integer> tarIndexs) {
this.tarIndexs = tarIndexs;
}
public void addLocation(int index) {
if (tarIndexs == null)
tarIndexs = new ArrayList<Integer>();
tarIndexs.add(index);
}
public void removeLocation(int index) {
if (tarIndexs == null) {
return;
}
tarIndexs.remove(tarIndexs.indexOf(index));
}
public int getOraIndex() {
return oraIndex;
}
public void setOraIndex(int oraIndex) {
this.oraIndex = oraIndex;
}
@Override
public String toString() {
return "WordBean{" +
"word='" + word + '\'' +
", tarIndexs=" + tarIndexs +
", oraIndex=" + oraIndex +
'}';
}
}
网友评论