Fancy looping in Java - java

I have a problem wherein I have two strings, the length of one of which I will know only upon execution of my function. I want to write my function such that it would take these two stings and based upon which one is longer, compute a final string as under -
finalString = longerStringChars1AND2
+ shorterStringChar1
+ longerStringChars3and4
+ shorterStringChar2
+ longerStringChars5AND6
...and so on till the time the SHORTER STRING ENDS.
Once the shorter string ends, I want to append the remaining characters of the longer string to the final string, and exit. I have written some code, but there is too much looping for my liking. Any suggestions?
Here is the code I wrote - very basic -
public static byte [] generateStringToConvert(String a, String b){
(String b's length is always known to be 14.)
StringBuffer stringToConvert = new StringBuffer();
int longer = (a.length()>14) ? a.length() : 14;
int shorter = (longer > 14) ? 14 : a.length();
int iteratorForLonger = 0;
int iteratorForShorter = 0;
while(iteratorForLonger < longer) {
int count = 2;
while(count>0){
stringToConvert.append(b.charAt(iteratorForLonger));
iteratorForLonger++;
count--;
}
if(iteratorForShorter < shorter && iteratorForLonger >= longer){
iteratorForLonger = 0;
}
if(iteratorForShorter<shorter){
stringToConvert.append(a.charAt(iteratorForShorter));
iteratorForShorter++;
}
else{
break;
}
}
if(stringToConvert.length()<32 | iteratorForLonger<b.length()){
String remainingString = b.substring(iteratorForLonger);
stringToConvert.append(remainingString);
}
System.out.println(stringToConvert);
return stringToConvert.toString().getBytes();
}

You can use StringBuilder to achieve this. Please find below source code.
public static void main(String[] args) throws InterruptedException {
int MAX_ALLOWED_LENGTH = 14;
String str1 = "yyyyyyyyyyyyyyyy";
String str2 = "xxxxxx";
StringBuilder builder = new StringBuilder(MAX_ALLOWED_LENGTH);
builder.append(str1);
char[] shortChar = str2.toCharArray();
int index = 2;
for (int charCount = 0; charCount < shortChar.length;) {
if (index < builder.length()) {
// insert 1 character from short string to long string
builder.insert(index, shortChar, charCount, 1);
}
// 2+1 as insertion index is increased after after insertion
index = index + 3;
charCount = charCount + 1;
}
String trimmedString = builder.substring(0, MAX_ALLOWED_LENGTH);
System.out.println(trimmedString);
}
Output
yyxyyxyyxyyxyy

String one = "longwordorsomething";
String two = "short";
String shortString = "";
String longString = "";
if(one.length() > two.length()) {
shortString = two;
longString = one;
} else {
shortString = one;
longString = two;
}
StringBuilder newString = new StringBuilder();
int j = 0;
for(int i = 0; i < shortString.length(); i++) {
if((j + 2) < longString.length()) {
newString.append(longString.substring(j, j + 2));
j += 2;
}
newString.append(shortString.substring(i, i + 1));
}
// Append last part
newString.append(longString.substring(j));
System.out.println(newString);

Related

Finding Count of Pattern in a String (Overlap Inclusive)

So I'm trying to write an algorithm that counts the number of occurrences of some pattern, say "aa", within a string, say "aaabca." The number of patterns in that string should return an integer, in this case 2, because the first three characters contain two occurrences of the pattern.
What I have finds the number of patterns under the assumption the existing occurrences of a pattern is NOT overlapping:
public class Pattern{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
System.out.println("Enter the string: ");
String s = scan.nextLine();
String[] splittedInput = s.split(";");
String pattern = splittedInput[0];
String blobs = splittedInput[1];
Pattern p = new Pattern();
p.count(pattern, blobs);
}
public static void count(String pattern, String blobs){
String[] substrings = blobs.split("[|]");
int numOccurences = 0;
int[] instances = new int[substrings.length];
int patternLength = pattern.length();
for (int i = 0; i < instances.length; i++){
int length = substrings[i].length();
String temp = substrings[i];
temp = temp.replaceAll(pattern, "");
int postLength = temp.length();
numOccurences = (length - postLength) / pattern.length();
instances[i] = numOccurences;
numOccurences = 0;
}
int sum = 0;
for (int i = 0; i < instances.length; i++){
System.out.print(instances[i] + "|");
sum += instances[i];
}
System.out.print(sum);
}
}
Any suggestions?
I would personally compare the pattern as a substring in this case. For example a run of a single String from your array would look like this:
//Initial values
String blobs = "aaaabcaaa";
String pattern = "aab";
String[] substrings = blobs.split("[|]");
//The code I added that should placed into the loop
int numOccurences = 0;
String str = substrings[0];
for (int k = 0; k <= (str.length() - pattern.length()); k++)
{
if (str.substring(k, k + pattern.length()).equals(pattern))
{
numOccurences++;
}
}
System.out.println(numOccurences);
If you want to run this on each String in your array simply modify String str = substrings[0] to String str = substrings[i] and iterate over the array storing the final numOccurences as you please.
Example Run:
String is aaaabcaaa
Pattern is aa
Output is 5 occurences
For one String, match is the String you're looking for:
int len = theStr.length ();
int start = 0;
int pos;
int count = 0;
while ((start < len) && ((pos = theStr.indexOf (match, start)) >= 0))
{
++count;
start = pos + 1;
}
If you use Java 8 you can count this value in the following way.
Example:
String blobs = "aaabcaaa";
String pattern = "aa";
List<String> strings = Arrays.asList(blobs.split(""));
long count = IntStream.range(0, strings.size())
.mapToObj(index -> index < strings.size() - 1 ? strings.get(index) + strings.get(index + 1) : strings.get(index - 1))
.filter(str -> str.equals(pattern))
.count();
System.out.println("Result count: " + count);
Continually taking substrings and using the startsWith method seems to work pretty well.
String pat = "ss";
String str = "kskslsksaaaslsslssskssssllsssss";
int count = 0;
while (str.length() >= pat.length()) {
count += str.startsWith(pat) ? 1 : 0;
str = str.substring(1);
}
System.out.println("count = " + count);
You can also take a similar approach with streams.
long count = IntStream.range(0, str.length()).mapToObj(
n -> str.substring(n)).filter(n -> n.startsWith(pat)).count();
System.out.println("count = " + count);
But in this case I actually prefer the non-stream approach.

parsing/converting task with characters and numbers within

It is necessary to repeat the character, as many times as the number behind it.
They are positive integer numbers.
case #1
input: "abc3leson11"
output: "abccclesonnnnnnnnnnn"
I already finish it in the following way:
String a = "abbc2kd3ijkl40ggg2H5uu";
String s = a + "*";
String numS = "";
int cnt = 0;
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (Character.isDigit(ch)) {
numS = numS + ch;
cnt++;
} else {
cnt++;
try {
for (int j = 0; j < Integer.parseInt(numS); j++) {
System.out.print(s.charAt(i - cnt));
}
if (i != s.length() - 1 && !Character.isDigit(s.charAt(i + 1))) {
System.out.print(s.charAt(i));
}
} catch (Exception e) {
if (i != s.length() - 1 && !Character.isDigit(s.charAt(i + 1))) {
System.out.print(s.charAt(i));
}
}
cnt = 0;
numS = "";
}
}
But I wonder is there some better solution with less and cleaner code?
Could you take a look below? I'm using a library from StringUtils from Apache Common Utils to repeat character:
public class MicsTest {
public static void main(String[] args) {
String input = "abc3leson11";
String output = input;
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher(input);
while (m.find()) {
int number = Integer.valueOf(m.group());
char repeatedChar = input.charAt(m.start()-1);
output = output.replaceFirst(m.group(), StringUtils.repeat(repeatedChar, number));
}
System.out.println(output);
}
}
In case you don't want to use StringUtils. You can use the below custom method to achieve the same effect:
public static String repeat(char c, int times) {
char[] chars = new char[times];
Arrays.fill(chars, c);
return new String(chars);
}
Using java basic string regx should make it more terse as follows:
public class He1 {
private static final Pattern pattern = Pattern.compile("[a-zA-Z]+(\\d+).*");
// match the number between or the last using regx;
public static void main(String... args) {
String s = "abc3leson11";
System.out.println(parse(s));
s = "abbc2kd3ijkl40ggg2H5uu";
System.out.println(parse(s));
}
private static String parse(String s) {
Matcher matcher = pattern.matcher(s);
while (matcher.find()) {
int num = Integer.valueOf(matcher.group(1));
char prev = s.charAt(s.indexOf(String.valueOf(num)) - 1);
// locate the char before the number;
String repeated = new String(new char[num-1]).replace('\0', prev);
// since the prev is not deleted, we have to decrement the repeating number by 1;
s = s.replaceFirst(String.valueOf(num), repeated);
matcher = pattern.matcher(s);
}
return s;
}
}
And the output should be:
abccclesonnnnnnnnnnn
abbcckdddijkllllllllllllllllllllllllllllllllllllllllggggHHHHHuu
String g(String a){
String result = "";
String[] array = a.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
//System.out.println(java.util.Arrays.toString(array));
for(int i=0; i<array.length; i++){
String part = array[i];
result += part;
if(++i == array.length){
break;
}
char charToRepeat = part.charAt(part.length() - 1);
result += repeat(charToRepeat+"", new Integer(array[i]) - 1);
}
return result;
}
// In Java 11 this could be removed and replaced with the builtin `str.repeat(amount)`
String repeat(String str, int amount){
return new String(new char[amount]).replace("\0", str);
}
Try it online.
Explanation:
The split will split the letters and numbers:
abbc2kd3ijkl40ggg2H5uu would become ["abbc", "2", "kd", "3", "ijkl", "40", "ggg", "2", "H", "5", "uu"]
We then loop over the parts and add any strings as is to the result.
We then increase i by 1 first and if we're done (after the "uu") in the array above, it will break the loop.
If not the increase of i will put us at a number. So it will repeat the last character of the part x amount of times, where x is the number we found minus 1.
Here is another solution:
String str = "abbc2kd3ijkl40ggg2H5uu";
String[] part = str.split("(?<=\\d)(?=\\D)|(?=\\d)(?<=\\D)");
String res = "";
for(int i=0; i < part.length; i++){
if(i%2 == 0){
res = res + part[i];
}else {
res = res + StringUtils.repeat(part[i-1].charAt(part[i-1].length()-1),Integer.parseInt(part[i])-1);
}
}
System.out.println(res);
Yet another solution :
public static String getCustomizedString(String input) {
ArrayList<String > letters = new ArrayList<>(Arrays.asList(input.split("(\\d)")));
letters.removeAll(Arrays.asList(""));
ArrayList<String > digits = new ArrayList<>(Arrays.asList(input.split("(\\D)")));
digits.removeAll(Arrays.asList(""));
for(int i=0; i< digits.size(); i++) {
int iteration = Integer.valueOf(digits.get(i));
String letter = letters.get(i);
char c = letter.charAt(letter.length()-1);
for (int j = 0; j<iteration -1 ; j++) {
letters.set(i,letters.get(i).concat(String.valueOf(c)));
}
}
String finalResult = "";
for (String str : letters) {
finalResult += str;
}
return finalResult;
}
The usage:
public static void main(String[] args) {
String testString1 = "abbc2kd3ijkl40ggg2H5uu";
String testString2 = "abc3leson11";
System.out.println(getCustomizedString(testString1));
System.out.println(getCustomizedString(testString2));
}
And the result:
abbcckdddijkllllllllllllllllllllllllllllllllllllllllggggHHHHHuu
abccclesonnnnnnnnnnn

Remove null from unused space of StringArray when converting to a string in Java

I was working on a Java coding problem and encountered the following issue.
Input: A String -> "Code"
Output Expected: A string -> CCoCodCode
My Code snippet: (Note: In comments I have written what I expect upon passing the string)
public String stringSplosion(String str) { // string Say 'Code'
String join = "", values = "";
String gotIt = "";
int n = str.length(); // 4
int size = 0;
for (int i = n; i >= 1; i--) {
size = size + n; // 4+3+2+1=10
}
String[] result = new String[size];
for (int i = 0; i < str.length(); i++) {
values = str.substring(i, i + 1);
join = join + values;
result[i] = join;
}
for (String s : result) {
gotIt = gotIt + s;
}
return gotIt; // Expected output: CCoCodCode
}
Output I am getting:
CCoCodCodenullnullnullnullnullnullnullnullnullnullnullnull
Why is null getting stored although I have reduced the size and how can I remove it?
NOTE: I need to solve this using arrays. I know it is much easier using List.
If you want to keep the current structure of your code, get rid of the first for loop.
And create String[] array = new String[n]
public static String stringSplosion(String str) { // string Say 'Code'
String join = "", values = "";
String gotIt = "";
int n = str.length(); // 4
String[] result = new String[n]; //you want your String array to contain 4 strings
for (int i = 0; i < str.length(); i++) {
values = str.substring(i, i + 1);
join = join + values;
result[i] = join;
}
for (String s : result) {
gotIt = gotIt + s;
}
return gotIt; // Expected output: CCoCodCode
}
public class Answer {
public static String answer(String input){
StringBuilder sb = new StringBuilder(((input.length() + 1) * input.length()) / 2);
for (int i = 1; i <= input.length(); i++) {
sb.append(input.substring(0, i));
}
return sb.toString();
}
public static void main(String[] args) {
System.out.println(answer("Code"));
}
}
Below statements are not required:
int size = 0;
for (int i = n; i >= 1; i--) {
size = size + n; // 4+3+2+1=10
}
You just need to change the array size from
String[] result = new String[size];
to
String[] result = new String[n];
for your program to give the expected output.
If I understand ur problem correctly to print the pattern then u can use below code,
public String printPattern(String input){
//Holds the iteration value by index
int previous=0;
//It holds the result characters
String result=null;
StringBuilder strBuilder=new StringBuilder();
//first loop to iterate only till input string length
for(int i=0;i<input.length();i++){
//checking iteration lenght with input string length
if(previous<input.length()){
//incrementing iteration for reading characters from input string
previous++;
//main loop for previous iteration value check and iterate
for(int j=0;j<previous;j++){
//converting string to Character array
char a []=input.toCharArray();
//using string builder to build the string from characters
strBuilder.append((a[j]));
//setting the value to stringbuilder by converting it in string
result=strBuilder.toString();
}
}
}
return result;
}
Size should be the length of string. Code's length is 4. Code will produce {C, Co, Cod, Code}.
public String stringSplosion(String str) { // string Say 'Code'
String join = "", values = "";
String gotIt = "";
int n = str.length(); // 4
String[] result = new String[n];
for (int i = 0; i < str.length(); i++) {
values = str.substring(i, i + 1);
join = join + values;
result[i] = join;
}
System.out.println(Arrays.toString(result));
for (String s : result) {
gotIt = gotIt + s;
}
return gotIt; // Expected output: CCoCodCode
}
String input = "Code";
String output[] = IntStream.range(0, input.length()+1)
.mapToObj(i -> input.substring(0, i))
.toArray(String[]::new);

how to convert "user_id" to "userId" in Java? [duplicate]

This question already has answers here:
What is the simplest way to convert a Java string from all caps (words separated by underscores) to CamelCase (no word separators)?
(22 answers)
Closed 7 years ago.
convert string to camelCase
eg:
"user_id" to "userId"
"user_name" to "userName"
"country_province_city" to "countryProvinceCity"
how to do that in a easy way?
ps:"country_province_city" should be "countryProvinceCity" not "countryprovincecity"
I would use a loop and a StringBuilder. Something like
String[] arr = { "user_id", "user_name", "country_province_city" };
for (String str : arr) {
StringBuilder sb = new StringBuilder(str);
int pos;
while ((pos = sb.indexOf("_")) > -1) {
String ch = sb.substring(pos + 1, pos + 2);
sb.replace(pos, pos + 2, ch.toUpperCase());
}
System.out.printf("%s = %s%n", str, sb);
}
And I get the (requested)
user_id = userId
user_name = userName
country_province_city = countryProvinceCity
As Fast Snail mentions, simply use, for example, if String str = "user_id, user_name, user_id";, call str = str.replaceAll("userID", "user_id");, causing str to now have the value "userID, user_name, userID"
Alternatively, a more complete method would be as follows
public String toCamel(String str) {
String[] splits = str.split("_");
for (int i = 1; i < splits.length; i++) {
char first = Character.toUpperCase(splits.charAt(0));
if (splits[i].length() > 0)
splits[i] = first + splits[i].substring(1);
else
splits[i] = first + "";
}
String toRet = "";
for (String s : splits)
toRet += s;
return toRet;
}
This is a very simple one:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String result = "";
String input = scan.nextLine();
for (int i = 0; i < input.length(); i++) {
if (input.charAt(i) == '_') {
result += input.toUpperCase().charAt(i + 1);
i = i + 1;
} else {
result += input.toLowerCase().charAt(i);
}
}
System.out.println(result);
}
if you like to do it many times, I advice you to use a while loop to keep repeating the same code over and over again:
while (true) {
//the previous code
}
http://commons.apache.org/proper/commons-lang/javadocs/api-3.4/index.html
String str="country_province_city";
wordUtils.capitalize(str, '_');
str=str.replaceAll("_", "");
output: countryProvinceCity
For another point of view that the answers above you can also do it with split function and two loops, like this:
String[] strings = {"user_id","user_name","country_province_city"};
for (int i = 0; i < strings.length; i++)
{
String string = strings[i];
String totalString = "";
String[] divide = string.split("_");
for(int j = 0; j < divide.length; j++)
{
if(j != 0)
{
divide[j] = "" + divide[j].toUpperCase().charAt(0) + divide[j].substring(1,divide[j].length());
}
totalString = totalString + divide[j];
}
}
If you want to show this changed Strings by console you just have to add System.out.println after the second loop and inside the first one, like this:
for (int i = 0; i < strings.length; i++)
{
//The same code as the code that I put in the example above
for(int j = 0; j < divide.length; j++)
{
//The same code as the example above
}
System.out.println(totalString);
}
On the contrary, if your objective it's to store them into an array, you can do it like this:
String[] store;
for (int i = 0; i < strings.length; i++)
{
//The same code as the code that I put in the example above
store = new String[divide.length];
for(int j = 0; j < divide.length; j++)
{
//The same code as the example above
}
store[j] = totalString;
}
If you have any doubt about the code please let me know.
I expect it will help to you!

Compress string longer than 2 - loops

Method to compress a string using java and loops. For example, if dc = "aabbbccaaaaba, then c = "aab3cca4ba" Here is what I have so far. Please help/guide. Thanks.
int cnt = 1;
String ans = "";
for (int i = 0; i < dc.length(); i++) {
if ((i < dc.length()) && (dc.charAt(i) == dc.charAt(i++)) && (dc.charAt(i) == dc.charAt(i+=2))){
cnt++;
ans = ans + dc.charAt(i) + cnt;
}
else
ans = ans + dc.charAt(i);
setC(ans);
Unless you're restricted to using for loops, I believe this would do the trick:
String sb = "";
for (int i = 0; i < dc.length(); i++) {
char c = dc.charAt(i);
int count = 1;
while (i + 1 < dc.length() && (dc.charAt(i + 1)) == c) {
count++;
i++;
}
if (count > 1) {
sb += count;
}
sb += c;
}
System.out.println(sb);
edit:
Changed the example to use regular String instead of StringBuilder. However, I really advise against concatenating strings this way, especially if the string you're trying to compress is long.
It might be easier to get what you want by using Sting.toCharArray().
Then manipulate the array accordingly.
String dc = "aabbbccaaaaba";
String and = "";
int index = 0;
int cnt = 2;
While(dc.charAt(index) != null){
int index1 = index + 1;
char j = dc.charAt(index)
While(j.equals(dc.charAt(index1)){
cnt++;
}
//more code
index++;
}
It's a little incomplete but if you follow the logic I think it's what you're looking for. I won't do your assignment for you.
Easiest Solution: - Only one for loop, Time Complexity - O(n)
public static void main(String[] args) {
String str = "aabbbccaaaaba";
char[] arr = str.toCharArray();
int length = arr.length;
StringBuilder sb = new StringBuilder();
int count=1;
for(int i=0; i<length; i++){
if(i==length-1){
sb.append(arr[i]+""+count);
break;
}
if(arr[i]==arr[i+1]){
count++;
}
else{
sb.append(arr[i]+""+count);
count=1;
}
}
System.out.println(sb.toString());
}

Categories

Resources