subString combined with the practices of the for loop - java

I get a long list of strings from the server
AS= String1 ~ String2 ~ String3 ~
Can be determined.
"~"Represents the end of each data.
I know that the word limit for each String of up to 22
But I do not know his actual length.
So I use this code to determine the value of each String
//////////////////////////Use of substring Get every character
String T1=AS.substring(0,1);
String T2=AS.substring(1,2);
.
.
.
String T22=AS.substring(21,22);
if (T2.equals("~")) {
DATA=T1;
}
if (T3.equals("~")) {
DATA=T1+T2;
}
//Confirm T3 "~" Get DATA = T2 + T1
String LG=LG+DATA.length()+1;
//The second document must be added to the number of words in the document "~"
String TT1=AS.substring(0+LG,1+LG);
Determine string of 100
Repeat 100 times
I have manufactured more than 8,000 lines of code
There is no easier way to reach my request?

Just a little bit to help you out.
String[] TKG = new String[GUY.length];
for (int i = 0; i < GUY.length - 1; i++)
{
TKG[i] = GUY.substring(i, i+1);
}
and then
StringBuilder DETA5 = new StringBuilder();
for (int i = 1; i < TKG.length; i++)
{
if (TKG[i].equals("~"))
{
for (int x = 0; x < i; x++)
{
DETA5.append(TKG[x]);
}
}
}
int D = D + DETA5.length();
String[] TKC = new String[6];
for (int i = 0; i < 6; i++)
{
TKC[i] = GUY.substring(i+D1, i + 1 + D1);
}
StringBuilder DETA_1_1 = new StringBuilder();
for (int i = 1; i < TKC.length; i++)
{
if (TKC[i].equals("~"))
{
for (int x = 0; x < i; x++)
{
DETA_1_1.append(TKC[x]);
}
}
}
Good Luck!

It looks almost as if a simple String#split(...) will do the trick for you. Have you tried something along the lines of
String[] tokens = guy.split("~");
Perhaps after a little cleaning up of the edge Strings, you'll have what you want.

Related

How do I repeat a string where each character is repeated a decreasing number of times?

Ah yes, I am back with another Java question. So here I am supposed to repeat a string where its characters repeat a decreasing number of times. The first character should be repeated the string's length number of times.
Here is an example of what the output should look like:
HHHHH
oooo
www
dd
y
What should I do next based on the code I have written below?
String go( String a)
{
String y = "";
for (int i = 0; i < a.length(); i++)
{
for (int j = 0; j < a.length(); j++)
{
y = y + a.charAt(i);
}
if (i == a.length() - 1)
{
y = y + "";
}
else
{
y = y + "\n";
}
}
return y;
}
Feel free to point out any obvious mistakes I have made. I am new to Java and just learned that Java and Javascript are not the same thing!
We can maintain two counters - 1 for extracting the character from string (characterLoc) and the other for specifying the number of times a character is to be repeated (repCount).
The outer while loop is used for extracting the character and inner loop is used for repeating the extracted character a specified number of times.
public static void main(String[] args) {
String str = "Howdy";
int characterLoc = 0;
int repCount = str.length();
while (characterLoc < str.length()) {
for (int x = repCount; x > 0; x--) {
System.out.print(str.charAt(characterLoc));
}
characterLoc++;
repCount--;
System.out.println();
}
}
When I ran the code you posted in your question, I got this result:
HHHHH
ooooo
wwwww
ddddd
yyyyy
which is not what you want.
In order to get what you want, you simply need to make one change in your code. You need to change the inner for loop. Here is your code with the required addition.
private static String go(String a) {
String y = "";
for (int i = 0; i < a.length(); i++) {
for (int j = 0; j < a.length() - i; j++) { // change here
y = y + a.charAt(i);
}
if (i == a.length() - 1) {
y = y + "";
}
else {
y = y + "\n";
}
}
return y;
}
When you run that code, it produces the following output.
HHHHH
oooo
www
dd
y
which is what you want, isn't it?

I'm not able to sort the splited strings properly using comparedTo method. What can I do to correct it?

This is my code, but I know this is not right. I have written a lot of code for such a simple task.
Sample input is:
welcome
Sample output is:
com
elc
lco
ome
wel
It should print:
your first string is 'com'
and
your last string is 'wel'
Code:
import java.io.*;
import java.util.*;
public class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
int k = sc.nextInt();
int k1 = k;
int j = 0;
int t = str.length();
String [] s = new String [1000];
for (int i = t, a = 0; i >= k; i--, a++) {
s[a] = str.substring(j, k1);
j++;
k1++;
}
String[] s1 = new String[j];
for (int i = 0 ; i < j; i++) {
s1[i] = s[i];
}
for (int y = 0; y < j; y++) {
for (int z = y + 1; z < j; z++) {
if(s1[z].compareTo(s1[y]) < 0) {
String temp = s1[z];
s1[z] = s1[y];
s1[y] = temp;
}
}
}
System.out.println(s1[0]);
System.out.println(s1[1]);
}
}
Note: I split my strings, but I'm not able to arrange strings in alphabetical order, and feel that I have used a lot of arrays. Is there a better way to do this?
You can
reduce the number of variables,
use collections (list in this case) instead of Arrays to avoid having to set a size (1000)
Sort using the framework
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
int k = sc.nextInt();
List<String> cutStrings = new ArrayList<String>();
for (int i = 0; i < str.length() - k; i++) {
cutStrings.add(str.substring(i, i + k));
}
Collections.sort(cutStrings);
System.out.println(cutStrings.get(0));
System.out.println(cutStrings.get(cutStrings.size()-1));
}
You can easily sort your String[] array by simply using
Arrays.sort(s);
This will sort your strings in the default order. If you need any other kind of order you can pass the comparator as a second parameter.
You can get first and last by getting s[0] and s[s.length-1]
I did a quick implementation of your requirements. It might not be exactly what you're looking for but it should get you started. :)
So, I used an ArrayList to grab the substrings and the use the Collections library to do the sorting for me. This is just one of the many ways of solving the problem, btw. The input word can vary in size so I felt that a list would be appropriate for this situation.
String s = "welcome";
List<String> words = new ArrayList<String>();
for (int i = 0; i < s.length() - 2; i++) {
String chunk = s.charAt(i) + "" + s.charAt(i + 1) + ""
+ s.charAt(i + 2);
words.add(chunk);
System.out.println(chunk);
}
Collections.sort(words);
System.out.println(words.toString());
Feel free to let me know if you have any questions or if I have made a mistake in the code.
Good luck!
Actual problem of your code is splitting. Sorting will work. If j value 1 and k1 value 3 then wel substring is coming. Next loop, (after incrementation of both j and k1 by 1) j value 2 and k1 value 4 then elc substring is coming, etc.
So, instead of
String [] s = new String [1000];
for (int i = t, a = 0; i >= k; i--, a++) {
s[a] = str.substring(j, k1);
j++;
k1++;
}
use
int k = sc.nextInt();
String [] s = new String [(str.length()/3)+1] ;
for ( int i = 0,a = 0; i<(str.length()-k); i+=k,a++)
{
s[a] = str.substring(i,(i+k));
System.out.println(s[a]);
}
s[s.length-1]=str.substring((str.length()-k),str.length());//to add remaining values
Arrays.sort(s);//sorting alphabatically
for(int i = 0; i < s.length; i++)
System.out.println(s[i]);
}
i value will be incremented by 3. In the for loop (i+=k) where k=3.
Output:
amp
com
e s
ple
wel

java one dimensional string to multidimensional

I am given a string that can represent hex values and am told to convert it to such and store it in a string:
String str = new String("FF E7 C3 E7 FF");
String[] arrayStr = str.split(" ");
Then I need to convert each hex value to its binary equivalent:
String[] arrayBin = new String[arrayStr.length];
for (int i = 0; i < arrayStr.length; i++) {
arrayBin[i] = Integer.toBinaryString(Integer.parseInt(arrayStr[i],16));
}
This is where I get lost. Is this binary string technically one dimensional or two dimensional? Basically, I need to convert it to a two dimensional array so that I can iterate through it in both x and y directions, to perform something like this:
for (int k = 0; k < arrayBin.length; k++) {
for (int l = 0; l < arrayBin[k].length; l++) {
if (arrayBin[k][l] == "1") {
arrayBin[k][l] = "x";
} else {
arrayBin[k][l] = " ";
}
}
}
At this point I get nothing but compiler errors, and despite all the articles online about multidimensional arrays, no search has given me something that works. I have tried things like:
String[][] arrayBin2 = new String[arrayBin.length][]
for (int m = 0; m < arrayBin.length; m++) {
arrayBin2[m][] = arrayBin[m];
}
But that did not work. Any help or suggestions as to what I am doing wrong would be greatly appreciated.
Second attempt in response to #Eran 's suggestions:
public class Challenge3 {
public static void main(String args[]) {
String str = new String("FF E7 C3 E7 FF");
String[] arrayStr = str.split(" ");
String[] arrayBin = new String[arrayStr.length];
for (int i = 0; i < arrayStr.length; i++) {
arrayBin[i] = Integer.toBinaryString(Integer.parseInt(arrayStr[i],16));
}
for (int k = 0; k < arrayBin.length; k++) {
StringBuilder sb = new StringBuilder(arrayBin[k].length());
for (int l = 0; l < arrayBin[k].length(); l++) {
if (arrayBin[k].charAt(l) == 1) {
sb.append("x");
} else {
sb.append(" ");
}
}
arrayBin[k] = sb.toString();
System.out.println(arrayBin);
}
}
}
As a side note, the code is supposed to print out the following when done correctly:
xxxxxxxx
xxx xxx
xx xx
xxx xxx
xxxxxxxx
Your arrayBin is 1-dimentional.
If you want to iterate over the bits of each binary String, use the methods length() and charAt() of the String class :
for (int k = 0; k < arrayBin.length; k++) {
StringBuilder sb = new StringBuilder(arrayBin[k].length());
for (int l = 0; l < arrayBin[k].length(); l++) {
if (arrayBin[k].charAt(l) == '1') {
sb.append ('x');
} else {
sb.append (' ');
}
}
arrayBin[k] = sb.toString();
System.out.println(arrayBin[k]);
}
Output :
xxxxxxxx
xxx xxx
xx xx
xxx xxx
xxxxxxxx
Note that you can't change the String instances in your arrayBin array, since String is immutable. What you can do is construct a new String and replace each String in the arrayBin array with the new String.

Finding the middle letter and make it uppercase.. am stuck and the end .. :(

Here am finding the middle letter of each element of the array and making it upper case and merge it so that it'll give me a result like e:g- {bOy, inDia, apPle}
Following is the code am trying till now.
public class FindMiddle {
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>();
al.add("boy india apple");
String str[] = al.toArray(new String[al.size()]);
String newar[];
String delimiter = " ";
newar = str[0].split(delimiter);
for (int i = 0; i < newar.length; i++) {
char[] c = newar[i].toCharArray();
for (int j = 0; j < c.length; j++) {
if (j == c.length / 2) {
c[j] = Character.toUpperCase(c[c.length / 2]);
System.out.println(c[j]);
}
newar[i] += c[j];
}
}
}
}
It's only giving me O D P.
I want them merged with the original elements like bOy inDia apPle.
that's because you print only the middle char (the println is inside the if statement)
if (j == c.length / 2) {
c[j] = Character.toUpperCase(c[c.length / 2]);
System.out.println(c[j]);
}
I would suggest using StringBuilder.setCharAt
for (int i = 0; i < newar.length; i++) {
StringBuilder updateString = new StringBuilder(newar[i]);
int middleIndex = newar[i].length /2;
updateString.setCharAt(middleIndex, Character.toUpperCase(newar[i].charAt(middleIndex));
System.out.println(updateString);
}
you could use the charAt function of the String object and replace function
using the full String.length is not accurate when you will be accessing the middle index of the String since index are length - 1 (because it starts with 0) so you need to deduct 1 from the length and then divide it by half.
for(int i=0;i<newar.length;i++){
int index = (newar[i].length()-1)/2;
newar[i] = newar[i].replace(newar[i].charAt(index), Character.toUpperCase(newar[i].charAt(index)));
System.out.println(newar[i]);
}
output:
bOy
inDia
aPPle
Try this :
for (int i = 0; i < newar.length; i++) {
char[] c = newar[i].toCharArray();
for (int j = 0; j < c.length; j++) {
if (j == c.length / 2) {
c[j] = Character.toUpperCase(c[c.length / 2]);
//System.out.print(c[j]); <--- you keep getting O D P because you
print them here
}
// newar[i] += c[j]; <-- here you just concat changed elements to newar
System.out.print(c[j]); <--- print the value of array none middle and middle one
}
if (i != newar.length-1) { <-- avoid printing , for last item
System.out.print(",");
}
}
output:
bOy,inDia,apPle
My explanations are as comment inside the code.
Note: when you are in a for loop, you are checking whether you ecnounter the middle character. if you encountered, you will make it uppercase other wise nothing is changed, and each character is printed out on the console.
import java.util.ArrayList;
public class Test
{
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>();
al.add("boy india apple");
String str[] = al.toArray(new String[al.size()]);
String newar[];
String delimiter = " ";
newar = str[0].split(delimiter);
for (int i = 0; i < newar.length; i++) {
char[] c = newar[i].toCharArray();
for (int j = 0; j < c.length; j++) {
if (j == c.length / 2) {
c[j] = Character.toUpperCase(c[c.length / 2]);
// System.out.println(c[j]);
// (1)
}
System.out.print(c[j]);
// (2)
newar[i] += c[j];
}
System.out.println();
// (3)
}
}
}
(1) - I got rid of this because it would only print out the uppercase letter. You had set the middle characters in all 3 words to uppercase, but, you need to print out the whole word, not just one letter.
(2) - You do, however, want to print out the whole word, which is what this line is doing. Instead of doing println, it only does print. Reason is because we are taking advantage of that for loop that is going through each character in the specific word to be able to print out each letter after we are done checking if it's the middle letter.
(3) - We have this line here because we want to be able to separate between words. I am not sure how you want these words separated so change this as you feel it's necessary, I just separated them so you could see.
There are a lot of things wrong with your code, so here is a simplified rewrite:
public static void main(String[] args) {
String s = "boy india apple";
String[] split = s.split( " " );
String[] toReturn = new String[split.length];
for (int i = 0; i < split.length;i++)
{
String word = split[i];
char[] chars = word.toCharArray();
chars[chars.length/2] = Character.toUpperCase( chars[chars.length/2] );
toReturn[i] = String.valueOf( chars );
}
System.out.println(Arrays.toString( toReturn ));
}
In order to correct your code you can start by removing the useless ArrayList and moving the System.out outside of the for loop. There are some other issues like you are appending the new result to the original so newar after this runs will look like {boybOy, indiainDia, appleapPle}.
EDIT:
For teaching purposes, here is your code modified so that it will work; however inefficient.
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>();
al.add("boy india apple");
String str[] = al.toArray(new String[al.size()]);
String newar[];
String delimiter = " ";
newar = str[0].split(delimiter);
System.out.print("{");
for (int i = 0; i < newar.length; i++) {
char[] c = newar[i].toCharArray();
for (int j = 0; j < c.length; j++) {
if (j == c.length / 2) {
c[j] = Character.toUpperCase(c[c.length / 2]);
}
System.out.print(c[j]);
}
newar[i] = String.valueOf(c);
if (i < newar.length - 1)
System.out.print(",");
}
System.out.println("}");
}
String temp = ""; //define temp string as "" (don't assign null)
for (int j = 0; j < c.length; j++) {
...
//newar[i] += c[j]; //don't append to existing String in array
temp += c[j];
newar[i] = temp;
}
//after replacement is done
//now can print replaced string in array by looping
for (String string : newar) {
System.out.println(string);
}

Getting all combinations of values from many lists

I'm trying to resolve all the combinations of elements based on a given string.
The string is like this :
String result="1,2,3,###4,5,###6,###7,8,";
The number of element between ### (separated with ,) is not determined and the number of "list" (part separated with ###) is not determined either.
NB : I use number in this example but it can be String too.
And the expected result in this case is a string containing :
String result = "1467, 1468, 1567, 1568, 2467, 2468, 2567, 2568, 3467, 3468, 3567, 3568"
So as you can see the elements in result must start with an element of the first list then the second element must be an element of the second list etc...
From now I made this algorithm that works but it's slow :
String [] parts = result.split("###");
if(parts.length>1){
result="";
String stack="";
int i;
String [] elmts2=null;
String [] elmts = parts[0].split(",");
for(String elmt : elmts){ //Browse root elements
if(elmt.trim().isEmpty())continue;
/**
* This array is used to store the next index to use for each row.
*/
int [] elmtIdxInPart= new int[parts.length];
//Loop until the root element index change.
while(elmtIdxInPart[0]==0){
stack=elmt;
//Add to the stack an element of each row, chosen by index (elmtIdxInPart)
for(i=1 ; i<parts.length;i++){
if(parts[i].trim().isEmpty() || parts[i].trim().equals(","))continue;
String part = parts[i];
elmts2 = part.split(",");
stack+=elmts2[elmtIdxInPart[i]];
}
//rollback i to previous used index
i--;
if(elmts2 == null){
elmtIdxInPart[0]=elmtIdxInPart[0]+1;
}
//Check if all elements in the row have been used.
else if(elmtIdxInPart[i]+1 >=elmts2.length || elmts2[elmtIdxInPart[i]+1].isEmpty()){
//Make evolve previous row that still have unused index
int j=1;
while(elmtIdxInPart[i-j]+1 >=parts[i-j].split(",").length ||
parts[i-j].split(",")[elmtIdxInPart[i-j]+1].isEmpty()){
if(j+1>i)break;
j++;
}
int next = elmtIdxInPart[i-j]+1;
//Init the next row to 0.
for(int k = (i-j)+1 ; k <elmtIdxInPart.length ; k++){
elmtIdxInPart[k]=0;
}
elmtIdxInPart[i-j]=next;
}
else{
//Make evolve index in current row, init the next row to 0.
int next = elmtIdxInPart[i]+1;
for(int k = (i+1) ; k <elmtIdxInPart.length ; k++){
elmtIdxInPart[k]=0;
}
elmtIdxInPart[i]=next;
}
//Store full stack
result+=stack+",";
}
}
}
else{
result=parts[0];
}
I'm looking for a more performant algorithm if it's possible. I made it from scratch without thinking about any mathematical algorithm. So I think I made a tricky/slow algo and it can be improved.
Thanks for your suggestions and thanks for trying to understand what I've done :)
EDIT
Using Svinja proposition it divide execution time by 2:
StringBuilder res = new StringBuilder();
String input = "1,2,3,###4,5,###6,###7,8,";
String[] lists = input.split("###");
int N = lists.length;
int[] length = new int[N];
int[] indices = new int[N];
String[][] element = new String[N][];
for (int i = 0; i < N; i++){
element[i] = lists[i].split(",");
length[i] = element[i].length;
}
// solve
while (true)
{
// output current element
for (int i = 0; i < N; i++){
res.append(element[i][indices[i]]);
}
res.append(",");
// calculate next element
int ind = N - 1;
for (; ind >= 0; ind--)
if (indices[ind] < length[ind] - 1) break;
if (ind == -1) break;
indices[ind]++;
for (ind++; ind < N; ind++) indices[ind] = 0;
}
System.out.println(res);
This is my solution. It's in C# but you should be able to understand it (the important part is the "calculate next element" section):
static void Main(string[] args)
{
// parse the input, this can probably be done more efficiently
string input = "1,2,3,###4,5,###6,###7,8,";
string[] lists = input.Replace("###", "#").Split('#');
int N = lists.Length;
int[] length = new int[N];
int[] indices = new int[N];
for (int i = 0; i < N; i++)
length[i] = lists[i].Split(',').Length - 1;
string[][] element = new string[N][];
for (int i = 0; i < N; i++)
{
string[] list = lists[i].Split(',');
element[i] = new string[length[i]];
for (int j = 0; j < length[i]; j++)
element[i][j] = list[j];
}
// solve
while (true)
{
// output current element
for (int i = 0; i < N; i++) Console.Write(element[i][indices[i]]);
Console.WriteLine(" ");
// calculate next element
int ind = N - 1;
for (; ind >= 0; ind--)
if (indices[ind] < length[ind] - 1) break;
if (ind == -1) break;
indices[ind]++;
for (ind++; ind < N; ind++) indices[ind] = 0;
}
}
Seems kind of similar to your solution. Does this really have bad performance? Seems to me that this is clearly optimal, as the complexity is linear with the size of the output, which is always optimal.
edit: by "similar" I mean that you also seem to do the counting with indexes thing. Your code is too complicated for me to go into after work. :D
My index adjustment works very simply: starting from the right, find the first index we can increase without overflowing, increase it by one, and set all the indexes to its right (if any) to 0. It's basically counting in a number system where each digit is in a different base. Once we can't even increase the first index any more (which means we can't increase any, as we started checking from the right), we're done.
Here is a somewhat different approach:
static void Main(string[] args)
{
string input = "1,2,3,###4,5,###6,###7,8,";
string[] lists = input.Replace("###", "#").Split('#');
int N = lists.Length;
int[] length = new int[N];
string[][] element = new string[N][];
int outCount = 1;
// get each string for each position
for (int i = 0; i < N; i++)
{
string list = lists[i];
// fix the extra comma at the end
if (list.Substring(list.Length - 1, 1) == ",")
list = list.Substring(0, list.Length - 1);
string[] strings = list.Split(',');
element[i] = strings;
length[i] = strings.Length;
outCount *= length[i];
}
// prepare the output array
string[] outstr = new string[outCount];
// produce all of the individual output strings
string[] position = new string[N];
for (int j = 0; j < outCount; j++)
{
// working value of j:
int k = j;
for (int i = 0; i < N; i++)
{
int c = length[i];
int q = k / c;
int r = k - (q * c);
k = q;
position[i] = element[i][r];
}
// combine the chars
outstr[j] = string.Join("", position);
}
// join all of the strings together
//(note: joining them all at once is much faster than doing it
//incrementally, if a mass concatenate facility is available
string result = string.Join(", ", outstr);
Console.Write(result);
}
I am not a Java programmer either, so I adapted Svinja's c# answer to my algorithm, assuming that you can convert it to Java also. (thanks to Svinja..)

Categories

Resources