String method with array of integers - java

Please help with code. I have tried adding substring, etc, to remove the end comma. How can I do this?
Example: {1,2,3} to string is now "1,2,3,"
public static String arrayToString(int[] numbers)
{
String stringify = "";
for (int index = 0; index < numbers.length; index++)
{
stringify = numbers[index] + ", ";
}
return stringify;
}

Best way
Delete the entire method. Use Arrays.toString(int[]) instead. Why rewrite core functionality like this?
Stream way
return Arrays.stream(numbers)
.boxed()
.map(String::valueOf)
.collect(Collectors.joining(", "));
StringBuilder way
StringBuilder out = new StringBuilder();
for (int i = 0; i < numbers.length; i++) {
if (i != 0) out.append(", ");
out.append(numbers[i]);
}
return out.toString();
Adding to a string in a loop is bad form (it wastes a ton of memory), so don't do that. The above strategies are in rough order of preference, with the top option miles ahead of the rest.

You can modify your method to the following one:
public static String arrayToString(int[] numbers)
{
String stringify = "";
for (int index = 0; index < numbers.length; index++)
{
stringify = numbers[index];
if (index < numbers.length - 1) {
stringify += ", ";
}
}
return stringify;
}

I prefer to view this as having a separator before every number except for the first. Or, equally, that there's a separator before every number, but the first separator is empty.
public static String arrayToString(int[] numbers)
{
String separator = "";
String stringify = "";
for (int index = 0; index < numbers.length; index++)
{
stringify += separator + numbers[index];
separator = ", "
}
return stringify;
}
Note, I fixed the assignment to stringify to be += rather than =, since otherwise you're just getting the last number.
In practice, I'd probably use a StringBuilder, but I wanted to leave this as close to the original as possible. With a StringBuilder, the same separator technique can be used.

Related

Reversing strings in Java (loops) until "done"

this is a lab for class I'm trying to do. Here's the instructions:
Write a program that takes in a line of text as input, and outputs that line of text in reverse. The program repeats, ending when the user enters "Done", "done", or "d" for the line of text.
Ex: If the input is:
"Hello there
Hey
done"
the output is:
"ereht olleH
yeH"
And here's what I have right now:
public class LabProgram {
public static void main(String[] args) {
/* Type your code here. */
Scanner scnr = new Scanner(System.in);
String[] inputs = new String[100];
String input;
int i = 0;
while (true) {
input = scnr.nextLine();
if(input.equals("Done") || input.equals("done") || input.equals("d"))
break;
inputs[i] = input;
i++;
}
for (int j = 0; j < i; j++) {
int length = inputs[j].length();
String reverse = "";
for (int k = length - i; k >= 0; k--) {
reverse = reverse + inputs[j].charAt(k);
}
System.out.print("\n" + reverse);
}
}
}
Current output
What am I doing wrong??
Iterate through the array, and reverse elements at every index.
This solution is time consuming but does your job
for (int j = 0; j < inputs.lenght; j++) {
int length = inputs[j].length();
char a;
String rev = "";
for(int i =0; i< length; i++){
a = inputs[j].charAt(i);
rev = a + rev;
}
System.out.println(rev);
}
*Try to use StringBuilder And use method reverse -- #Artur Todeschini
To add to what Artur said, an ArrayList of StringBuilders could do the trick quite well:
for(StringBuilder nextEntry : stringBuilderList)
{
nextEntry.reverse();
}
The enhanced for-loop will go through each entry in the ArrayList, and the StringBuilder's reverse will change the order of the letters.
EDIT TO SHOW FORMATTING
ArrayList<StringBuilder> stringBuilderList= new ArrayList<>();
*note. given that this is for a lab, its probably for learning purposes and using built-in classes that does all the work for you are usually not the intended solution. -- #experiment unit 1998X
Try to use StringBuilder
And use method reverse
This is another "ArrayList and StringBuilder-less" version.
Create two Strings, one filled and one empty:
String nextString = stringArray[i],
template = new String();
Loop through the length of the String, adding the next character in from the end each time through.
int length = nextString.length() - 1;
for(int j = 0; j < length; j++)
{
template += nextString.charAt(length - j);
}
Add the whole String to the String array's index
stringArray[i] = template;
NOTE
This is an inner loop for a String array and is NOT complete code

What's wrong with my algorithm that's giving me incorrect duplicate removal values?

I'm trying to remove duplicates in a string but I'm not sure why my algorithm's wrong. It's giving me an output of baa instead of bans which's the correct output.
During my attempt to debug, I tried switching the i to j inside sb.deleteCharAt(); but that gave me a Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 5 error.
What am I doing wrong and how can I fix this?
Here's my code:
public static void removeDuplicate(String s) {
StringBuilder sb = new StringBuilder(s);
for(int i = 0; i < s.length(); i++) {
for(int j = i + 1; j < s.length(); j++) {
if(s.charAt(i) == s.charAt(j)) {
sb.deleteCharAt(i);
}
}
}
System.out.print("Duplicates have been, the resulting string is => " + sb);
}
public static void main(String[] args) {
String s = "bananas";
removeDuplicate(s);
}
There are a couple of things that are wrong. You should make the comparison with string builder in your loops, not with string itself, as it changes. Second, you're using wrong index in removal. Here's the correct program:
public static void removeDuplicate(String s) {
StringBuilder sb = new StringBuilder(s);
for(int i = 0; i < sb.length(); i++) {
for(int j = i + 1; j < sb.length(); j++) {
if(sb.charAt(i) == sb.charAt(j)) {
sb.deleteCharAt(j);
}
}
}
System.out.print("Duplicates have been, the resulting string is => " + sb);
}
public static void main(String[] args) {
String s = "bananas";
removeDuplicate(s);
}
The output is:
Duplicates have been, the resulting string is => bans
You can use distinct() :
StringBuilder sb = new StringBuilder();
yourstr.chars().distinct().forEach(c -> sb.append((char) c));
Best
Well, deleting elements from a collection while loop through it is a bad idea, because it can cause wrong logic base on index changes.
Just put some special case like "baaana", your solution will fail easily because when you trying to found "a" at index 2, you remove it and skip comparing with the "actual" index 3 because its index is decreased to 2 after removing.
And another thing you should know. In Java, String is immutable, that means when you change a string, you actually assign the variable with the new one. So those function should return a new String instead of modifying input.
With this type of problem, i suggest you should use a hash data type to memorize the distinct elements, so you can solve this with an O(n) time complexity.
public static String removeDuplicate(String s) {
StringBuilder sb = new StringBuilder();
Set<Character> metChars = new HashSet<>();
for(int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if(!metChars.contains(c)) {
sb.append(c);
metChars.add(c);
}
}
return sb.toString();
}
Basically, when you remove a character in your StringBuilder, you effectively change the indexes of all further characters.
In your example bananas, if you remove the second a (pos 3 since we start at 0), you get the string bannas. Then, when you want to remove the 3rd a of bananas, at pos 5, you end up removing the s.

Is converting to String the most succinct way to remove the last comma in output in java?

So basically this is how my code looked like
public static void printPrime(int[] arr)
{
int len = arr.length;
for(int i = 0; i < len; i++)
{
int c = countFactor(arr[i]);
if(c == 2)
{
System.out.print(arr[i] + ",");
}
}
}
So the output did have the 'comma' in the end. I tried looking around to remove the last comma some answers say to print last element separately but that can only happen when output depends on the for loop and not the if condition.
But as you can see I don't know how many elements I am going to get from the if condition. Only two things I can think of, to add another loop or use String then substr to output.
So I converted it to String
public static void printPrime(int[] arr)
{
int len = arr.length;
String str = "";
for(int i = 0; i < len; i++)
{
int c = countFactor(arr[i]);
if(c == 2)
{
str = str + arr[i] + ",";
}
}
str = str.substring(0, str.length()-1);
System.out.println(str);
}
My question is about knowing the optimum way (converting to string then substringing it?) for similar questions or could there be a better way as well? That I seem to be missing.
You don't have to construct a string. Consider the following slight tweaks:
public static void printPrime(int[] arr)
{
int len = arr.length;
String sep = ""; // HERE
for(int i = 0; i < len; i++)
{
int c = countFactor(arr[i]);
if(c == 2)
{
System.out.print(sep); // HERE
sep = ",";
System.out.print(arr[i]);
}
}
}
Print the delimiter first, and store its value in a variable: the first time it's printed, it will print the empty string. Thereafter, it prints the comma.
Whatever means you use should operate correctly for an empty array (length 0), a singleton array (length 1) and a long array (a large length).
Adding the comma then removing it requires special case handling for the empty array case. So you must have conditional code (an if statement) whatever you do.

Substring alternative

So I'm creating a program that will output the first character of a string and then the first character of another string. Then the second character of the first string and the second character of the second string, and so on.
I created what is below, I was just wondering if there is an alternative to this using a loop or something rather than substring
public class Whatever
{
public static void main(String[] args)
{
System.out.println (interleave ("abcdefg", "1234"));
}
public static String interleave(String you, String me)
{
if (you.length() == 0) return me;
else if (me.length() == 0) return you;
return you.substring(0,1) + interleave(me, you.substring(1));
}
}
OUTPUT: a1b2c3d4efg
Well, if you really don't want to use substrings, you can use String's toCharArray() method, then you can use a StringBuilder to append the chars. With this you can loop through each of the array's indices.
Doing so, this would be the outcome:
public static String interleave(String you, String me) {
char[] a = you.toCharArray();
char[] b = me.toCharArray();
StringBuilder out = new StringBuilder();
int maxLength = Math.max(a.length, b.length);
for( int i = 0; i < maxLength; i++ ) {
if( i < a.length ) out.append(a[i]);
if( i < b.length ) out.append(b[i]);
}
return out.toString();
}
Your code is efficient enough as it is, though. This can be an alternative, if you really want to avoid substrings.
This is a loop implementation (not handling null value, just to show the logic):
public static String interleave(String you, String me) {
StringBuilder result = new StringBuilder();
for (int i = 0 ; i < Math.max(you.length(), me.length()) ; i++) {
if (i < you.length()) {
result.append(you.charAt(i)); }
if (i < me.length()) {
result.append(me.charAt(i));
}
}
return result.toString();
}
The solution I am proposing is based on the expected output - In your particular case consider using split method of String since you are interleaving by on character.
So do something like this,
String[] xs = "abcdefg".split("");
String[] ys = "1234".split("");
Now loop over the larger array and ensure interleave ensuring that you perform length checks on the smaller one before accessing.
To implement this as a loop you would have to maintain the position in and keep adding until one finishes then tack the rest on. Any larger sized strings should use a StringBuilder. Something like this (untested):
int i = 0;
String result = "";
while(i <= you.length() && i <= me.length())
{
result += you.charAt(i) + me.charAt(i);
i++;
}
if(i == you.length())
result += me.substring(i);
else
result += you.substring(i);
Improved (in some sense) #BenjaminBoutier answer.
StringBuilder is the most efficient way to concatenate Strings.
public static String interleave(String you, String me) {
StringBuilder result = new StringBuilder();
int min = Math.min(you.length(), me.length());
String longest = you.length() > me.length() ? you : me;
int i = 0;
while (i < min) { // mix characters
result.append(you.charAt(i));
result.append(me.charAt(i));
i++;
}
while (i < longest.length()) { // add the leading characters of longest
result.append(longest.charAt(i));
i++;
}
return result.toString();
}

Delete next two characters in string with indexOf and map

i have a problem with a algorithm.
I have a Map (Each key int its a hex unicode character) and a String with unicode characters.
I want to delete the next character in the string when i found a character that exists as key in my map.
for example my map contains those keys: 0x111,0x333,0x444,0x555,0x666 and my string its:
0x111+0xffff+0x444+0xEEEEE+0x666
I want to convert it to:
0x111+0x444+0x666
I have this but this doesnt work:
private String cleanFlags(String text) {
int textLong = text.length();
for (int i = 0; i < textLong; i++) {
if (flagCountryEmojis.containsKey(text.codePointAt(text.charAt(i)))) {
text = text.replace(text.substring(i + 1, i + 2), "");
textLong-=2;
}
}
return text;
}
How can i do it this?
Since you didn't mention anything about space complexity, I went ahead and took the liberties of using an array to solve the question:
public String cleanFlags(String text){
String [] arr = text.split("+");
String newText = "";
for(int i = 0; i < arr.length; i++){
if(flagCountryEmojis.containsKey(arr[i])){
newText += arr[i];
i++; // skips the next character
}
if(i < arr.length - 1)
newText += "+";
}
return newText;
}
Not sure if this solution solves your problem, since strings are immutable anyways, and calling "replace" simply creates a new string in the background, I went ahead and created a new string for you and returned the result when it is populated correctly.
Lemme know if there is something I am missing or other restrictions that were unmentioned.

Categories

Resources