假设您获得了包含以下内容的数组:
约旦
JORD
安娜
罗布
RobJord
你想要返回一个包含Jord的所有值的数组(即Jord,Jordan,RobJord),这是最强高效的方法。
我正在使用Java,但我不允许使用java.util数组函数。
答案 0 :(得分:2)
我想到了这种方法:
public ArrayList<String> search(String searchString, String[] names)
{
ArrayList<String> searchList = new ArrayList<String>();
for (String name : names)
{
if(name.contains(searchString))
{
searchList.add(name);
}
}
return searchList;
}
现在要搜索,请使用:
String[] names = {"Jordan", "Jord", "Anna", "Rob", "RobJord"};
String searchString = "Jord";
ArrayList<String> filterList = search(searchString, names);
它不使用java.util.Arrays
方法,并且还以干净的方式完成工作,更不用说,它的速度很快。
现在如果你甚至不能使用ArrayList
,那么你有两个选择:
1.自己实施ArrayList
并使用它。
2.请遵循以下方法:
public String[] search(String searchString, String[] names)
{
int size = getSize(searchString, names);
String[] searchList = new String[size];
int index = 0;
for (String name : names)
{
if(name.contains(searchString))
{
searchList[index++] = name;
}
}
return searchList;
}
// Returns appropriate size for the Search List
private int getSize(String searchString, String[] names)
{
int size = 0;
for (String name : names)
{
if(name.contains(searchString))
{
size++;
}
}
return size;
}
答案 1 :(得分:1)
好吧,因为这听起来像家庭作业,它是你解决,但我会考虑这个非常英国的伪代码。它避免使用java.util.*
(例如ArrayList或Arrays类)并且只使用原始构造。
count = 0
for each item in the input
if the rule matches
increase count by 1
create output array of size count
target index = 0
for each item in the input
if the rule matches
add the item to the output array at the target index,
and increase the target index by 1
return the output array
此代码在complexity中为O(n)
,即使它循环输入(n
)两次,因为这是一个常数因素,而O(2*n)
是2*O(n)
}是O(n)
。
现在,常量边界可以稍微减少,而不是只计算第一遍,也压缩第一遍的值,然后只复制压缩值(小于或等于n
)到一个新的较小数组。它仍然是O(n)
,但可能的挂钟时间略低......或者它可能会执行更糟,具体取决于细微的缓存/ JIT /数据因素。哦,现代计算机的复杂功能!
改善O(n)
“效率”界限并没有什么微不足道的方法 - 特别是对于一次运行没有。
答案 2 :(得分:0)
需要一些代码来设置所有内容并且它将是可怕的样式,但是你可以将你的字符串转换为字符串数组,并且有一个 int 数组,表示“Jord”中字母的ascii值,这样您就可以获得通过原语而不是对象引用进行检查的好处。将您正在检查的字符传递给条件块,该块使用
的int值对其进行求值 'J', 'o', 'r', 'd' //74, 111, 114, 100
同样,我只是建议这种疯狂,因为你非常注重效率。马上我会说,将所有东西转移到字符上都需要时间效率。在大型处理任务中可以获得最大的好处,例如在整个1000页的电子书中检查Jord,因为初始化只发生一次(或者在大块中,我想也许有大量数据,但无论哪种方式都有益)
//assuming its case sensitive: ascii values for 'J' 'o' 'r' 'd'
int[] charArr = new int[]{74, 111, 114, 100};
同样,它需要一些设置来阻碍性能,加上它只是奇怪,但它确实给你带来了原始int验证的好处。
另一个想法是考虑某些字母的统计数字后跟另一个字母。例如,“J”跟随任何元音的可能性非常高,因此“J”后跟“o”但仍然不是“Jord”因此非常高,因为我们只有5个元音(加y,奇怪的一个...)你可能会得到“Jork”,你浪费了检查“o”和“r”。所以说到这一点,也许最好将扫描仪向上移动几个字母(或你当前的数组索引计数器 - 无论你迭代哪种方式),在你为“J”建立匹配后检查“d” ”。我认为这会提高效率。
基本上我是说如果你以一种迭代方式逐字逐句地检查它,那么第一步是匹配“J”,然后第二步是跳过< / em>“o”并检查“r”或“d”。或者换句话说,找一个候选人,并积极地消除候选人
编辑:我实际上是说在步骤2中检查“d”并且如果步骤2检出,则不考虑检查“r”直到步骤3,因为这样你的代码会更简单 - 从头开始,移动到最后,然后向后迭代到开始+ 1。如果在步骤2中检查“r”,那么步骤3和4将是锯齿形索引以遍历