Reverse a list while also changing capslock and space - java

I'm pretty new to java and i am not understanding how i would combine these two things. What i am trying to do is reverse the list while also removing the space and capslock in between the letters and add something at the end to the output. Can you tell me what is wrong with what I am doing? This is to be created using a string builder
StringBuilder sb = new StringBuilder("We need ");
for (int i = tools.length - 1; i >= 0; i--) {
sb.append(tools[i]);
}
this part is gonna reverse the list and
for (String s : tools) {
sb.append(s.toLowerCase().trim() + "s, ");
}
this part is gonna lowercase and trim all the non essential stuff. How do I combine these two parts together when Im coding. Really not getting it
so for example if the input is an array of list
String[] tools = {"\tfood", "TABLE", " car ", "Phone"};
the output is going to be We need phones, cars, tables, foods and much more.

StringBuilder sb = new StringBuilder("We need ");
StringBuilder sbend = new StringBuilder();
for (int i = tools.length - 1; i >= 0; i--) {
sb.append(i).append(tools[i]);
sbend.append(tools[tools.length-i-1].toLowerCase().trim() + "s, ");
}
sb.append(sbend);
Just have two stringbuilders. Forget using string functions on integers. integers can't be put to lowercase or trimmed.
For your loop issue you first put your first line items in the first string builder and the reverse part in the second.
then when the loop is finished you join the two.

If this is the output you are expecting
We need phone, car, table, food
Then maybe you can try something like this-
for (int i = tools.length - 1; i >= 0; i--) {
sb.append(tools[i].toLowerCase().replaceAll("\\s+", ""));
if (i != 0) {
sb.append(", ");
}
}

Using StringBuilder and String, it seems to be as simple as below:
StringBuilder sb = new StringBuilder("We need ");
String s;
sb.reverse();
s = sb.substring(0).toLowerCase().replaceAll("\\s+","");
System.out.println(s);
Using only StringBuilder:
StringBuilder sb = new StringBuilder("We need ");
StringBuilder sb0 = new StringBuilder();
for (int i = sb.length() - 1; i >= 0; i--) {
sb0.append(sb.substring(i, i+1).toLowerCase().replace(" ", ""));
}
System.out.println(sb0);

String[] tools = {"\tfood", "TABLE", " car ", "Phone" };
StringBuilder need = new StringBuilder( "We need " );
String del = "";
for( int i = tools.length - 1; i >= 0; --i ){
need.append( del );
need.append( tools[i].trim().toLowerCase() );
need.append( "s" );
del = ", ";
}
need.append( " and much more." );
System.out.println( need.toString() );
This prints
We need phones, cars, tables, foods and much more.

Related

Is it possible to display strings with new line inline

I have 2 strings
String str1 = "FIRST \n SECOND"
String str2 = "FIRST \n SECOND"
Is it possible for it to be displayed like this?
FIRST FIRST
SECOND SECOND
I do not think that you can do that with simple print statements.
What you can try, on the other hand, would be to have a list of string builders, one for each line. You would then split the string by \n and you place each item in the array in the next string builder.
Once that you would have finished, you would then simply need to traverse the list of string builders and print the content.
So basically (untested code, should give you an idea of what needs doing though):
List<StringBuilders> list = new ArrayList<>();
String str = '...';
String[] parsedLine = str.split("\\n");
for(int i = 0; i < parsedLine.length;i++) {
if(list.size() <= i) list.add(new StringBuilder());
list.get(i).append(parsedLine + "\t");
}
for(StringBuilder sb : list) {
System.out.println(sb.toString());
}
You May use first split and rejoin it using white space. it will work sure.
String finalString = "";
String[] finalStringArray = inputString.split("[\\n]+");
for(int i = 0; i<finalStringArray.lengh; i++){
finalString = finalString+" "+finalStringArray[i];
}

Split string after every 2 words and store into list

I have a string of words as follows:
String words = "disaster kill people action scary seriously world murder loose world";
Now, I wish to split every 2 words and store them into a list so that it will produce something like:
[disaster kill, people action, scary seriously,...]
The problem with my code is that it will split whenever it encounters a space. How do I modify it so that it will only be added into the list if it only encounters every 2nd space, preserving the space after each word)
My code:
ArrayList<String> wordArrayList = new ArrayList<String>();
for(String word : joined.split(" ")) {
wordArrayList.add(word);
}
Thanks.
Use this regular expression: (?<!\\G\\S+)\\s.
PROOF:
String words = "disaster kill people action scary seriously world murder loose world";
String[] result = words.split("(?<!\\G\\S+)\\s");
System.out.printf("%s%n", Arrays.toString(result));
And the result:
[disaster kill, people action, scary seriously, world murder, loose world]
Your loop should leave you with an ArrayList<String> that has each word, right? All you need to do now is iterate through that list and combine words together in sets of twos.
ArrayList<String> finalList = new ArrayList<String>();
for (int i = 0; i < wordArrayList.Size(); i+=2) {
if (i + 1 < wordArrayList.Size()
finalList.add(wordArrayList.get(i) + " " + wordArrayList.get(i + 1);
}
This should take your split words and add them to the list with spaces so that they look like your desired output.
I was looking for splitting a string after 'n' words.
So I modify the above solution.
private void spiltParagraph(int splitAfterWords, String someLargeText) {
String[] para = someLargeText.split(" ");
ArrayList<String> data = new ArrayList<>();
for (int i = 0; i < para.length; i += splitAfterWords) {
if (i + (splitAfterWords - 1) < para.length) {
StringBuilder compiledString = new StringBuilder();
for (int f = i; f <= i + (splitAfterWords - 1); f++) {
compiledString.append(para[f] + " ");
}
data.add(compiledString.toString());
}
}
}
I run into this problem today, adding an extra difficulty that is to write this solution in Scala. So, I needed to write a recursive solution that looks like:
val stringToSplit = "THIS IS A STRING THAT WE NEED TO SPLIT EVERY 2 WORDS"
#tailrec
def obtainCombinations(
value: String,
elements: List[String],
res: List[String]
): List[String] = {
if (elements.isEmpty)
res
else
obtainCombinations(elements.head, elements.tail, res :+ value + ' ' + elements.head)
}
obtainCombinations(
stringToSplit.split(' ').head,
stringToSplit.split(' ').toList.tail,
List.empty
)
The output will be:
res0: List[String] = List(THIS IS, IS A, A STRING, STRING THAT, THAT WE, WE NEED, NEED TO, TO SPLIT, SPLIT EVERY, EVERY 2, 2 WORDS)
Porting this to Java would be:
String stringToSplit = "THIS IS A STRING THAT WE NEED TO SPLIT EVERY 2 WORDS";
public ArrayList<String> obtainCombinations(String value, List<String> elements, ArrayList<String> res) {
if (elements.isEmpty()) {
return res;
} else {
res.add(value + " " + elements.get(0));
return obtainCombinations(elements.get(0), elements.subList(1, elements.size()), res);
}
}
ArrayList<String> result =
obtainCombinations(stringToSplit.split(" ")[0],
Arrays.asList(stringToSplit.split(" ")),
new ArrayList<>());

How to connect strings from an array in java

I'm creating a bukkit plugin and one of its features is to show the plugins on the server, here's my code that handles the plugin listing:
for(int i = 0; i < plugins.length; i++){
String conplugin = plugins[i].toString();
String[] conplugin2 = conplugin.split(" ");
if(i + 1 == plugins.length) {
pluginlist.add(ChatColor.BLUE + conplugin2[0]);
} else {
pluginlist.add(ChatColor.BLUE + conplugin2[0] + ChatColor.DARK_GRAY + ", " );
}
}
I want to get all the strings from the array (pluginlist) and make one string out of them.
If you want to construct a String from a String array, you could use a for loop and append the array element to the end of your new string.
StringBuilder newString = new StringBuilder ();
for (int i = 0; i < arr.length; i++) {
newString.append (arr [i]);
}
return newString;
You could also use a String, but depending on the size of the array of plugins, it would probably be faster to create a StringBuilder.
Use a StringBuilder as it is mutable and you can append to it. Strings are immutable hence you can't change it.
You can use the previous StringBuilder example.

Compare content of two text files and split words java

I know this question has been already asked several times but I can't find the way to apply it on my code.
So my propose is the following:
I have two files griechenland_test.txt and outagain5.txt . I want to read them and then get which percentage of outagain5.txt is inside the other file.
Outagain5 has input like that:
mit dem 542824
und die 517126
And Griechenland is an normal article from Wikipedia about that topic (so like normal text, without freqeuncy Counts).
1. Problem
- How can I split the input in bigramms? Like every two words, but always with the one before? So if I have words A, B, C, D --> get AB, BC, CD ?
I have this:
while ((sCurrentLine = in.readLine()) != null) {
// System.out.println(sCurrentLine);
arr = sCurrentLine.split(" ");
for (int i = 0; i < arr.length; i++) {
if (null == hash.get(arr[i])) {
hash.put(arr[i], 1);
} else {
int x = hash.get(arr[i]) + 1;
hash.put(arr[i], x);
}
}
Then I read the other file with this code ( I just add the word, and not the number (I split it with 4 spaces, so the two words are at h[0])).
for (String line = br.readLine(); line != null; line = br.readLine()) {
String h[] = line.split(" ");
words.add(h[0]);
}
2. Problem
Now I make the comparsion between the String x in hash and the String s in words. I have put the else System out.print to get which words are not contained in outagain5.txt, but there are several words printed out which ARE contained in outagain5.txt. I don't understand why :D
So I think that the comparsion doesn't work well or maybe this will be solved will fix the first problem.
ArrayList<String> words = new ArrayList<String>();
ArrayList<String> neuS = new ArrayList<String>();
ArrayList<Long> neuZ = new ArrayList<Long>();
for (String x : hash.keySet()) {
summe = summe + hash.get(x);
long neu = hash.get(x);
for (String s : words) {
if (x.equals(s)) {
neuS.add(x);
neuZ.add(neu);
disc = disc + 1;
} else {
System.out.println(x);
break;
}
}
}
Hope I made my question clear, thanks a lot!!
public static List<String> ngrams(int n, String str) {
List<String> ngrams = new ArrayList<String>();
String[] words = str.split(" ");
for (int i = 0; i < words.length - n + 1; i++)
ngrams.add(concat(words, i, i+n));
return ngrams;
}
public static String concat(String[] words, int start, int end) {
StringBuilder sb = new StringBuilder();
for (int i = start; i < end; i++)
sb.append((i > start ? " " : "") + words[i]);
return sb.toString();
}
It is much easier to use the generic "n-gram" approach so you can split every 2 or 3 words if you want. Here is the link I used to grab the code from: I have used this exact code almost any time I need to split words in the (AB), (BC), (CD) format. NGram Sequence.
If I recall, String has a method titled split(regex, count) that will split the item according to a specific point and you can tell it how many times to do it.
I am referencing this JavaDoc https://docs.oracle.com/javase/6/docs/api/java/lang/String.html#split(java.lang.String, int).
And I guess for running comparison between two text files I would recommend having your code read both of them, populated two unique arrays and then try to run comparisons between the two strings each time. Hope I helped.

Last iteration of enhanced for loop in java

Is there a way to determine if the loop is iterating for the last time. My code looks something like this:
int[] array = {1, 2, 3...};
StringBuilder builder = new StringBuilder();
for(int i : array)
{
builder.append("" + i);
if(!lastiteration)
builder.append(",");
}
Now the thing is I don't want to append the comma in the last iteration. Now is there a way to determine if it is the last iteration or am I stuck with the for loop or using an external counter to keep track.
Another alternative is to append the comma before you append i, just not on the first iteration. (Please don't use "" + i, by the way - you don't really want concatenation here, and StringBuilder has a perfectly good append(int) overload.)
int[] array = {1, 2, 3...};
StringBuilder builder = new StringBuilder();
for (int i : array) {
if (builder.length() != 0) {
builder.append(",");
}
builder.append(i);
}
The nice thing about this is that it will work with any Iterable - you can't always index things. (The "add the comma and then remove it at the end" is a nice suggestion when you're really using StringBuilder - but it doesn't work for things like writing to streams. It's possibly the best approach for this exact problem though.)
Another way to do this:
String delim = "";
for (int i : ints) {
sb.append(delim).append(i);
delim = ",";
}
Update: For Java 8, you now have Collectors
It might be easier to always append. And then, when you're done with your loop, just remove the final character. Tons less conditionals that way too.
You can use StringBuilder's deleteCharAt(int index) with index being length() - 1
Maybe you are using the wrong tool for the Job.
This is more manual than what you are doing but it's in a way more elegant if not a bit "old school"
StringBuffer buffer = new StringBuffer();
Iterator iter = s.iterator();
while (iter.hasNext()) {
buffer.append(iter.next());
if (iter.hasNext()) {
buffer.append(delimiter);
}
}
This is almost a repeat of this StackOverflow question. What you want is StringUtils, and to call the join method.
StringUtils.join(strArr, ',');
Another solution (perhaps the most efficient)
int[] array = {1, 2, 3};
StringBuilder builder = new StringBuilder();
if (array.length != 0) {
builder.append(array[0]);
for (int i = 1; i < array.length; i++ )
{
builder.append(",");
builder.append(array[i]);
}
}
keep it simple and use a standard for loop:
for(int i = 0 ; i < array.length ; i ++ ){
builder.append(array[i]);
if( i != array.length - 1 ){
builder.append(',');
}
}
or just use apache commons-lang StringUtils.join()
Explicit loops always work better than implicit ones.
builder.append( "" + array[0] );
for( int i = 1; i != array.length; i += 1 ) {
builder.append( ", " + array[i] );
}
You should wrap the whole thing in an if-statement just in case you're dealing with a zero-length array.
As toolkit mentioned, in Java 8 we now have Collectors. Here's what the code would look like:
String joined = array.stream().map(Object::toString).collect(Collectors.joining(", "));
I think that does exactly what you're looking for, and it's a pattern you could use for many other things.
If you convert it to a classic index loop, yes.
Or you could just delete the last comma after it's done. Like so:
int[] array = {1, 2, 3...};
StringBuilder
builder = new StringBuilder();
for(int i : array)
{
builder.append(i + ",");
}
if(builder.charAt((builder.length() - 1) == ','))
builder.deleteCharAt(builder.length() - 1);
Me, I just use StringUtils.join() from commons-lang.
You need Class Separator.
Separator s = new Separator(", ");
for(int i : array)
{
builder.append(s).append(i);
}
The implementation of class Separator is straight forward. It wraps a string that is returned on every call of toString() except for the first call, which returns an empty string.
Based on java.util.AbstractCollection.toString(), it exits early to avoid the delimiter.
StringBuffer buffer = new StringBuffer();
Iterator iter = s.iterator();
for (;;) {
buffer.append(iter.next());
if (! iter.hasNext())
break;
buffer.append(delimiter);
}
It's efficient and elegant, but not as self-evident as some of the other answers.
Here is a solution:
int[] array = {1, 2, 3...};
StringBuilder builder = new StringBuilder();
bool firstiteration=true;
for(int i : array)
{
if(!firstiteration)
builder.append(",");
builder.append("" + i);
firstiteration=false;
}
Look for the first iteration :)
Yet another option.
StringBuilder builder = new StringBuilder();
for(int i : array)
builder.append(',').append(i);
String text = builder.toString();
if (text.startsWith(",")) text=text.substring(1);
Many of the solutions described here are a bit over the top, IMHO, especially those that rely on external libraries. There is a nice clean, clear idiom for achieving a comma separated list that I have always used. It relies on the conditional (?) operator:
Edit: Original solution correct, but non-optimal according to comments. Trying a second time:
int[] array = {1, 2, 3};
StringBuilder builder = new StringBuilder();
for (int i = 0 ; i < array.length; i++)
builder.append(i == 0 ? "" : ",").append(array[i]);
There you go, in 4 lines of code including the declaration of the array and the StringBuilder.
Here's a SSCCE benchmark I ran (related to what I had to implement) with these results:
elapsed time with checks at every iteration: 12055(ms)
elapsed time with deletion at the end: 11977(ms)
On my example at least, skipping the check at every iteration isn't noticeably faster especially for sane volumes of data, but it is faster.
import java.util.ArrayList;
import java.util.List;
public class TestCommas {
public static String GetUrlsIn(int aProjectID, List<String> aUrls, boolean aPreferChecks)
{
if (aPreferChecks) {
StringBuffer sql = new StringBuffer("select * from mytable_" + aProjectID + " WHERE hash IN ");
StringBuffer inHashes = new StringBuffer("(");
StringBuffer inURLs = new StringBuffer("(");
if (aUrls.size() > 0)
{
for (String url : aUrls)
{
if (inHashes.length() > 0) {
inHashes.append(",");
inURLs.append(",");
}
inHashes.append(url.hashCode());
inURLs.append("\"").append(url.replace("\"", "\\\"")).append("\"");//.append(",");
}
}
inHashes.append(")");
inURLs.append(")");
return sql.append(inHashes).append(" AND url IN ").append(inURLs).toString();
}
else {
StringBuffer sql = new StringBuffer("select * from mytable" + aProjectID + " WHERE hash IN ");
StringBuffer inHashes = new StringBuffer("(");
StringBuffer inURLs = new StringBuffer("(");
if (aUrls.size() > 0)
{
for (String url : aUrls)
{
inHashes.append(url.hashCode()).append(",");
inURLs.append("\"").append(url.replace("\"", "\\\"")).append("\"").append(",");
}
}
inHashes.deleteCharAt(inHashes.length()-1);
inURLs.deleteCharAt(inURLs.length()-1);
inHashes.append(")");
inURLs.append(")");
return sql.append(inHashes).append(" AND url IN ").append(inURLs).toString();
}
}
public static void main(String[] args) {
List<String> urls = new ArrayList<String>();
for (int i = 0; i < 10000; i++) {
urls.add("http://www.google.com/" + System.currentTimeMillis());
urls.add("http://www.yahoo.com/" + System.currentTimeMillis());
urls.add("http://www.bing.com/" + System.currentTimeMillis());
}
long startTime = System.currentTimeMillis();
for (int i = 0; i < 300; i++) {
GetUrlsIn(5, urls, true);
}
long endTime = System.currentTimeMillis();
System.out.println("elapsed time with checks at every iteration: " + (endTime-startTime) + "(ms)");
startTime = System.currentTimeMillis();
for (int i = 0; i < 300; i++) {
GetUrlsIn(5, urls, false);
}
endTime = System.currentTimeMillis();
System.out.println("elapsed time with deletion at the end: " + (endTime-startTime) + "(ms)");
}
}
Another approach is to have the length of the array (if available) stored in a separate variable (more efficient than re-checking the length each time). You can then compare your index to that length to determine whether or not to add the final comma.
EDIT: Another consideration is weighing the performance cost of removing a final character (which may cause a string copy) against having a conditional be checked in each iteration.
If you're only turning an array into a comma delimited array, many languages have a join function for exactly this. It turns an array into a string with a delimiter between each element.
In this case there is really no need to know if it is the last repetition.
There are many ways we can solve this. One way would be:
String del = null;
for(int i : array)
{
if (del != null)
builder.append(del);
else
del = ",";
builder.append(i);
}
Two alternate paths here:
1: Apache Commons String Utils
2: Keep a boolean called first, set to true. In each iteration, if first is false, append your comma; after that, set first to false.
Since its a fixed array, it would be easier simply to avoid the enhanced for... If the Object is a collection an iterator would be easier.
int nums[] = getNumbersArray();
StringBuilder builder = new StringBuilder();
// non enhanced version
for(int i = 0; i < nums.length; i++){
builder.append(nums[i]);
if(i < nums.length - 1){
builder.append(",");
}
}
//using iterator
Iterator<int> numIter = Arrays.asList(nums).iterator();
while(numIter.hasNext()){
int num = numIter.next();
builder.append(num);
if(numIter.hasNext()){
builder.append(",");
}
}
You can use StringJoiner.
int[] array = { 1, 2, 3 };
StringJoiner stringJoiner = new StringJoiner(",");
for (int i : array) {
stringJoiner.add(String.valueOf(i));
}
System.out.println(stringJoiner);

Categories