题目描述
请设计一个高效算法,再给定的字符串数组中,找到包含"Coder"的字符串(不区分大小写),并将其作为一个新的数组返回。结果字符串的顺序按照"Coder"出现的次数递减排列,若两个串中"Coder"出现的次数相同,则保持他们在原数组中的位置关系。
给定一个字符串数组A和它的大小n,请返回结果数组。保证原数组大小小于等于300,其中每个串的长度小于等于200。同时保证一定存在包含coder的字符串。
测试样例:
["i am a coder","Coder Coder","Code"],3
返回:
["Coder Coder","i am a coder"]
先来说明一下这个题目:
1、刚开始做题时认为给的字符串是用空格隔开的,这样导致出现第一种解题方案。
2、由于所有测试用例不能完全通过,修改后将原字符串不管是有没有空格隔开的,都能输出相应的字符串数组。
3、但是所有测试用例不能完全通过,原因是字符串中出现相同字符串的没有按照原先的顺序打印,因此出现了方案三。
方案三能通过牛客网的所有测试用例。
再次说明:方案一:解决原字符串是用空格隔开的;
方案二:不区分字符串格式(包含或不包含空格);但出现次数相同的字符串输出顺序不能按照输入顺序打印;
方案三:不区分字符串格式(包含或不包含空格);能按照次数相同的字符串输出顺序按照输入顺序打印。
方案一:原字符串是用空格隔开
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
* 题目描述:
* 请设计一个高效算法,再给定的字符串数组中,找到包含"Coder"的字符串(不区分大小写),并将其作为一个新的数组返回。
* 结果字符串的顺序按照"Coder"出现的次数递减排列,若两个串中"Coder"出现的次数相同,则保持他们在原数组中的位置关系。
* 给定一个字符串数组A和它的大小n,请返回结果数组。保证原数组大小小于等于300,其中每个串的长度小于等于200。同时保证一定存在包含coder的字符串。
* 测试样例: ["i am a coder","Coder Coder","Code"],3
* 返回:["Coder Coder","i am a coder"]
*
* @author 崔洪振367
* @version 创建时间:2017年7月2日 上午9:28:09
*/
public class 寻找Coder {
public static void main(String[] args) {
String[] A = {"i am a coder","Coder Coder","Code"};
String[] B = {"coder","dccoderrlcoderxxpicoderhcoderbiwcoderdcoderrcodermcoderdbvcodertrwvycoderimvcoderuswfccoderczecoderczncoderkfuehcoderocoderiuvccoderfwcodervdiycoderifqjcoder","vxroicoderdqcoderfvcodermtyrcoderlcoderwrygcoder","hcoderwzmjccoderamfmvcoderazmcoderhcodersnuccoderceocodermsmifcoderpwpcodertqbqcoderentbcoderxsgpkcoderrqrbcoderucoder"};
int n = 3;
String[] strings = findCoder(A, n);
for(int i=0; i<strings.length; i++){
System.out.println(strings[i]);
}
}
public static String[] findCoder(String[] A, int n) {
if(A == null || n == 0){
return null;
}
HashMap<String, Integer> hashMap = new HashMap<>();
//下边是对字符串中包含coder单词的数目的统计,并记录
for(int i=0; i<n; i++){
String temp = A[i].toLowerCase();
//int temps_num = countStr(temp, "coder");
String[] temps = temp.split("\\s");
int temps_num = 0;
for(int j=0; j<temps.length; j++){
String te = temps[j].toLowerCase();
if(te.contains("coder")){
temps_num++;
}
}
hashMap.put(temp, temps_num);
}
//下边是对HashMap的值进行排序
List<Map.Entry<String, Integer>> list = new LinkedList<Map.Entry<String,Integer>>(hashMap.entrySet());
Collections.sort(list, new Comparator<Map.Entry<String, Integer>>(){
@Override
public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
//System.out.println(o1.getValue()-o2.getValue() == 0 ? o1.getValue()-o2.getValue() : o2.getValue()-o1.getValue());
return o1.getValue()-o2.getValue() == 0 ? o1.getValue()-o2.getValue() : o2.getValue()-o1.getValue();
}
});
List<String> list2 = new LinkedList<String>();
for(Map.Entry<String, Integer> mapping : list){
int num = mapping.getValue();
if(num > 0){
list2.add(mapping.getKey());
}
}
int length = list2.size();
String[] res = new String[length];
for(int k=0; k<length; k++){
res[k] = list2.get(k);
}
return res;
}
public static int countStr(String str1, String str2){
int count = 0;
if(str1.indexOf(str2) == -1){
return 0;
}
while(str1.indexOf(str2) != -1){
count++;
str1 = str1.substring(str1.indexOf(str2)+str2.length());
}
return count;
}
}
输出结果:
coder coder
i am a coder
方案二:不区分字符串格式(包含或不包含空格),不按照输入顺序输出
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
* 题目描述:
* 请设计一个高效算法,再给定的字符串数组中,找到包含"Coder"的字符串(不区分大小写),并将其作为一个新的数组返回。
* 结果字符串的顺序按照"Coder"出现的次数递减排列,若两个串中"Coder"出现的次数相同,则保持他们在原数组中的位置关系。
* 给定一个字符串数组A和它的大小n,请返回结果数组。保证原数组大小小于等于300,其中每个串的长度小于等于200。同时保证一定存在包含coder的字符串。
* 测试样例: ["i am a coder","Coder Coder","Code"],3
* 返回:["Coder Coder","i am a coder"]
*
* @author 崔洪振367
* @version 创建时间:2017年7月2日 上午9:28:09
*/
public class 寻找Coder2 {
public static void main(String[] args) {
String[] A = {"i am a coder","Coder Coder","Code"};
//String[] B = {"coder","dccoderrlcoderxxpicoderhcoderbiwcoderdcoderrcodermcoderdbvcodertrwvycoderimvcoderuswfccoderczecoderczncoderkfuehcoderocoderiuvccoderfwcodervdiycoderifqjcoder","vxroicoderdqcoderfvcodermtyrcoderlcoderwrygcoder","hcoderwzmjccoderamfmvcoderazmcoderhcodersnuccoderceocodermsmifcoderpwpcodertqbqcoderentbcoderxsgpkcoderrqrbcoderucoder"};
int n = 3;
String[] strings = findCoder(A, n);
for(int i=0; i<strings.length; i++){
System.out.println(strings[i]);
}
}
public static String[] findCoder(String[] A, int n) {
if(A == null || n == 0){
return null;
}
HashMap<String, Integer> hashMap = new HashMap<>();
//下边是对字符串中包含coder单词的数目的统计,并记录
for(int i=0; i<n; i++){
String temp = A[i];
String[] temps = temp.split("\\s");
int temps_num = 0;
for(int j=0; j<temps.length; j++){
String te = temps[j].toLowerCase();
if(te.contains("coder")){
temps_num++;
}
}
hashMap.put(temp, temps_num);
}
//下边是对HashMap的值进行排序
List<Map.Entry<String, Integer>> list = new LinkedList<Map.Entry<String,Integer>>(hashMap.entrySet());
Collections.sort(list, new Comparator<Map.Entry<String, Integer>>(){
@Override
public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
return o1.getValue()-o2.getValue() == 0 ? o1.getValue()-o2.getValue() : o2.getValue()-o1.getValue();
}
});
List<String> list2 = new LinkedList<String>();
for(Map.Entry<String, Integer> mapping : list){
int num = mapping.getValue();
if(num > 0){
list2.add(mapping.getKey());
}
}
int length = list2.size();
String[] res = new String[length];
for(int k=0; k<length; k++){
res[k] = list2.get(k);
}
return res;
}
}
方案三:不区分字符串格式(包含或不包含空格),按照输入顺序输出
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import org.junit.Test;
/**
* 题目描述: 请设计一个高效算法,再给定的字符串数组中,找到包含"Coder"的字符串(不区分大小写),并将其作为一个新的数组返回。
* 结果字符串的顺序按照"Coder"出现的次数递减排列,若两个串中"Coder"出现的次数相同,则保持他们在原数组中的位置关系。
* 给定一个字符串数组A和它的大小n,请返回结果数组。保证原数组大小小于等于300,其中每个串的长度小于等于200。同时保证一定存在包含coder的字符串。
* 测试样例: ["i am a coder","Coder Coder","Code"],3
* 返回:["Coder Coder","i am a coder"]
*
* @author 崔洪振367
* @version 创建时间:2017年7月2日 上午10:51:37
*/
public class 寻找Coder3 {
@Test
public void main() {
String[] A = {"i am a coder","Coder Coder","Code"};
String[] B = {"coder","dccoderrlcoderxxpicoderhcoderbiwcoderdcoderrcodermcoderdbvcodertrwvycoderimvcoderuswfccoderczecoderczncoderkfuehcoderocoderiuvccoderfwcodervdiycoderifqjcoder","vxroicoderdqcoderfvcodermtyrcoderlcoderwrygcoder","hcoderwzmjccoderamfmvcoderazmcoderhcodersnuccoderceocodermsmifcoderpwpcodertqbqcoderentbcoderxsgpkcoderrqrbcoderucoder"};
int n = 3;
String[] strings = findCoder(B, 4);
for(int i=0; i<strings.length; i++){
System.out.println(strings[i]);
}
}
/**
* @param A 字符串数组
* @param n 字符串数组的大小
* @return 返回值是字符串数组,存放满足条件的字符串
*/
public String[] findCoder(String[] A, int n){
ArrayList<Recoder> result = new ArrayList<Recoder>();
for(int index=0; index<n; index++){
String temp = A[index].toLowerCase();
int count = getStrNum(temp, "coder");
result.add(new Recoder(temp, index, count));
}
Collections.sort(result, new Comparator<Recoder>() {
@Override
public int compare(Recoder o1, Recoder o2) {
//先按照count--单词出现的次数降序排序
if(o1.count != o2.count){
return o2.getCount() - o1.getCount();
}else{
//若count相等则按照index(原数组顺序)排序
return o1.getIndex() - o2.getIndex();
}
}
});
int num = 0;
for(Recoder r : result){
if(r.getCount() != 0){
num++;
}
}
int k = 0;
String[] res = new String[num];
for(Recoder r : result){
if(r.getCount() != 0){
res[k++] = r.getData();
}
}
return res;
}
/**
* @param str1 原字符串
* @param str2 待查找的字符串
* @return 返回值是str2字符串在str1字符串中出现的次数
*/
public int getStrNum(String str1, String str2){
int count = 0;
if(str1.indexOf(str2) == -1){
return 0;
}
while(str1.indexOf(str2) != -1){
count++;
str1 = str1.substring(str1.indexOf(str2)+str2.length());
}
return count;
}
class Recoder{
private String data;//字符串
private int index;//在原数组中的位置
private int count;//包含coder字符串的个数
public Recoder(String data, int index, int count){
this.data = data;
this.index = index;
this.count = count;
}
public String getData(){
return data;
}
public int getIndex(){
return index;
}
public int getCount(){
return count;
}
}
}
注:只有方案三能通过所有测试用例。在牛客网可以测试的。