please for help
I need retrurn in 'String dst;' the same result as console
e.g. input txt = "aabbc"; which gives return dst = "a2b2c1"
public String compres(String txt) {
String dst = "";
char character;
int count;
for (int i = 0; i < txt.length(); i++) {
character = txt.charAt(i);
count = 1;
while (i < txt.length() - 1 && txt.charAt(i + 1) == character) {
count++;
i++;
}
System.out.print(character);
System.out.print(count);
}
return dst;
}
Use StringBuilder.
public String compres(String txt) {
StringBuilder dst = new StringBuilder();
char character;
int count;
for (int i = 0; i < txt.length(); i++) {
character = txt.charAt(i);
count = 1;
while (i < txt.length() - 1 && txt.charAt(i + 1) == character) {
count++;
i++;
}
System.out.print(character);
System.out.print(count);
dst.append(character).append(count);
}
return dst.toString();
}
today my mate gave me easiest sollution i need add only in my loop:
dst += character + "" + count;
instead of double sysout
Related
Given a string, I want to compress the string based on each character's number of consecutive occurrences next to it. For example, let's say we have a string like "abaasass". 'a' occurs one time, 'b' occurs one time, 'a' occurs two times consecutively, 's' occurs one time, 'a' occurs one time, and 's' occurs two times consecutively. The method should then return a string like "aba2sas2".
This is what I have so far:
public static String compressedString(String message) {
StringBuilder compressedString = new StringBuilder();
int total = 0;
for (int i = 0; i < message.length() - 1; i++){
if (message.charAt(i) == message.charAt(i+1)){
total += 2;
compressedString.append(message.charAt(i)).append(total);
}
else {
compressedString.append(message.charAt(i));
}
total = 0;
}
return compressedString.toString();
}
It instead returns: "aba2asas2" which is somewhat close, anyone sees the issue?
public static String compressedString(String message) {
StringBuilder compressedString = new StringBuilder();
int total = 1;
for (int i = 0; i < message.length() - 1; i++){
if (message.charAt(i) == message.charAt(i+1)){
total++;
}
else if(total==1){
compressedString.append(message.charAt(i));
}
else
{
compressedString.append(message.charAt(i)).append(total);
total = 1;
}
}
if(message.charAt(message.length()-2) != message.charAt(message.length()-1)
compressedString.append(message.charAt(message.length()-1));
else
compressedString.append(message.charAt(message.length()-1)).append(total);
return compressedString.toString();
}
public static String compressedString(String message)
{
String result = "" ;
for ( int i = 0, t = message.length() - 1 ; i < t ; )
{
String letter = String.valueOf( message.charAt(i) ) ;
int currentChain = consec( i, message ) ;
result += ( currentChain > 1 ? ( letter + currentChain ) : letter ) ;
i += currentChain ;
}
return result ;
}
private static int consec( int startIndex, String text )
{
int chain = 1 ;
for( int i = startIndex ; i < text.length() - 1 ; ++i )
{
if( text.charAt(i) == text.charAt(i+1) )
chain++ ;
else
break ;
}
return chain ;
}
This is your solution for your question
static void compressedString(String str) {
int n = str.length();
for (int i = 0; i < n; i++) {
// Count occurrences of current character
int count = 1;
while (i < n - 1 && str.charAt(i) == str.charAt(i + 1)) {
count++;
i++;
}
if (count == 1) {
System.out.print(str.charAt(i));
} else {
System.out.print(str.charAt(i));
System.out.print(count);
}
}
}
public static void main(String[] args) {
String str = "abaasass";
compressedString(str);
}
I'm trying to count the number of times a letter appears in a string (aabcccccaaa) and placing the number of times that it does into a new string along with the corresponding letter. The problem's that I get a StringIndexOutOfBoundsException.
I kind of have a clue why but I think it's mainly because my logic is flawed with this problem.
Am I on the right track? What am I doing wrong and how can I fix it?
For example, the output should be a2b1c5a3
Here's my code:
public class Problem {
public static void main(String []args) {
String str = "aabcccccaaa";
System.out.println(compressBad(str));
}
public static String compressBad(String str) {
int countConsecutive = 0;
String compressedString = "";
for(int i = 0; i < str.length(); i++) {
if(str.charAt(i) != str.charAt(i + 1)) {
countConsecutive++;
compressedString += "" + str.charAt(i) + countConsecutive;
countConsecutive = 0;
}
}
return compressedString;
}
}
This line str.charAt(i + 1) will read out of bounds when i is the last index, i+1 is now out of bounds.
For what it's worth, here's what I would do :
public static String compressBad(final String str) {
if (str == null || str.length() < 0) {
return "";
}
int countConsecutive = 0;
StringBuilder sb = new StringBuilder();
char previousLetter = str.charAt(0);
for (char c : str.toCharArray()) {
if (c == previousLetter) {
countConsecutive++;
} else {
sb.append(previousLetter).append(countConsecutive);
previousLetter = c;
countConsecutive = 1;
}
}
sb.append(previousLetter).append(countConsecutive);
return sb.toString();
}
I'm trying to display the number of times a letter appears within a string and outputting it in a new string (compressedString).
For example: aabcccccaaa should display a2b1c5a3.
So far, I got a2 to display only because I've included the break statement. If I took that out, then I would get StringIndexOutOfBoundsException.
My question is: How would I continue going through the whole string to obtain the rest of the aforementioned output without getting StringIndexOutOfBoundsException?
I ran it through debugger but it still isn't clear to me.
public class Problem {
public static void main(String []args) {
String str = "aabcccccaaa";
System.out.println(compressBad(str));
}
public static String compressBad(String str) {
int countConsecutive = 0;
String compressedString = "";
for(int i = 0; i < str.length(); i++) {
countConsecutive++;
if(str.charAt(i) != str.charAt(i + 1)) {
compressedString += "" + str.charAt(i) + countConsecutive;
break;
}
}
return compressedString;
}
}
modify your for loop to terminate when i < str.length() - 1--this is because you are comparing the character at i to the character at i + 1, which makes your loop go out of bounds.
Try this
public class Problem {
public static void main(String []args) {
String str = "aaabc";
System.out.println(compressBad(str));
}
public static String compressBad(String str) {
int countConsecutive = 0;
String compressedString = "";
for(int i = 0; i < str.length(); i++) {
countConsecutive++;
//avoid index out of bounds error
if(str.length() == (i + 1)){
compressedString += ""+ str.charAt(i) + countConsecutive;
countConsecutive = 0;
break;
}
else if(str.charAt(i) != str.charAt(i + 1)){
compressedString += ""+ str.charAt(i) + countConsecutive;
countConsecutive = 0;
}
}
return compressedString;
}
}
The other answers have good solutions, but I thought I would just add what I came up with:
public class Problem {
public static void main(String []args) {
String str = "aabcccccaaa";
System.out.println(compressBad(str));
}
public static String compressBad(String str) {
if (str.length() == 1) return str + "1"; // Handles single character strings
int countConsecutive = 0;
String compressedString = "";
for (int i = 0; i < str.length(); i++) {
if (i > 0) {
countConsecutive++;
if (str.charAt(i) != str.charAt(i-1)) {
compressedString += "" + str.charAt(i-1) + countConsecutive;
countConsecutive = 0;
}
if (i == str.length()-1) {
countConsecutive++; // Needs to be incremented for the last character
compressedString += "" + str.charAt(i) + countConsecutive;
}
}
}
return compressedString;
}
}
Your condition should be like this:
if(i+1 < str.length() && str.charAt(i) != str.charAt(i + 1))
because when you are is at last index of your string then also you are comparing i'th index with i+1 th index.
But after correcting this, still, this code will not give you the expected output.
This is how I would change the code.
public static String compressBad(String str) {
String compressedString = "";
if (str != null && str.length() > 0) {
int countConsecutive = 1;
char prevChar = str.charAt(0);
for (int i = 1; i < str.length(); i++) {
if (str.charAt(i) != prevChar) {
// End of a run. Update compressedString and reset counters
compressedString += String.valueOf(prevChar) + countConsecutive;
prevChar = str.charAt(i);
countConsecutive = 1;
continue;
}
countConsecutive++;
}
compressedString += String.valueOf(prevChar) + countConsecutive;
}
return compressedString;
}
Mukit09 has already mentioned the reason for your StringIndexOutOfBoundsException.
I offer you a more efficient implementation, using String Builder for concatenating strings:
private static String comppressedString(String str) {
if(str == null || str.equals("")) {
return str;
}
if(str.length() == 1) {
return str + "1";
}
StringBuilder sb = new StringBuilder();
sb.append(str.charAt(0)); // Add first letter
int j = 1; // Counter for current sequence length.
for (int i = 0; i < str.length() - 1; i++) {
if(str.charAt(i) != str.charAt(i + 1)) { // end of characters sequence.
sb.append(j); // Add length of previous sequence.
if(j > 1) {
j = 1; // Minimum sequence length is 1
}
sb.append(str.charAt(i+1)); // Add character of next sequence.
} else {
j++; // increase counter, in order to get the length of the current sequence.
}
}
sb.append(j); // Add length of last sequence.
return sb.toString();
}
public static void main(String[] args) {
System.out.println(comppressedString("")); // empty string
System.out.println(comppressedString("a")); // a1
System.out.println(comppressedString("ab")); // a1b1
System.out.println(comppressedString("abba")); // a1b2a1
System.out.println(comppressedString("aabcccccaaa")); // a2b1c5a3
}
Im at a point in my program where I need to set marks in a string before I pass it through another method, I have it so that every 4th char will have a "|" inserted, this is to mark a row break. Not I want to take each char in between the outter marks "|" and put a ",". that two char array method wont work here otherwise I would have tryed to use that but I'm not looking for a char array.
public static String matrixFormatter(String x){
x = x.substring(0, 4) + "|" + x.substring(4, x.length());
return x;
}
this works so far, now I want to add a "," between each char, I thought the code below would work and this would be easy but I was wrong.
public static String matrixFormatter(String x){
for(int i = 0; i<=x.length(); i+=4){
for(int j = 0; j<=x.length(); i++){
x = x.substring(0, i) + "|" + x.substring(i, x.length());
x = x.substring(0, j) + "|" + x.substring(j, x.length());
}
}
return x;
}
The code below adds a "," between characters in the string.
public static String matrixFormatter(String x){
String result;
for(int i = 0; i<x.length()-1; i++){
result += x.substring(i, i+1) + ",";
}
return result+",";
}
try this regex
s = s.replaceAll("(?<=.)(?=.)", ",");
It can be done with StringBuffer and also with Joiner of Guava library:
public static void main(String[] args) {
String s = "example";
System.out.println(withBuilder(s));
System.out.println(withJoiner(s));
}
private static String withJoiner(String s) {
return Joiner.on(",").join(Chars.asList(s.toCharArray()));
}
private static String withBuilder(String s)
{
StringBuilder builder = new StringBuilder(s);
int index = 1;
for (int i = 0; i < s.length() ; i++)
{
builder.insert(index, ",");
index +=2;
}
return builder.toString();
}
Output is:
e,x,a,m,p,l,e,
e,x,a,m,p,l,e
It can be done in one method:
public static String matrixFormatter(String x) {
List<String> chars = Arrays.asList(x.split(""));
String result = chars.get(0);
for (int i = 1; i < chars.size(); i++) {
if (i % 4 == 0)
result += "|" + chars.get(i);
else
result += "," + chars.get(i);
}
return result;
}
calling with:
System.out.println(matrixFormatter("12345678"));
outputs:
1,2,3,4|5,6,7,8
public static String matrixFormatter(String x) {
resultstr = "";
int i = 0;
while(i < x.length()) {
// If end of string: only add character.
if (i == x.length() - 1) {
resultstr += x.substring(i, i + 1);
} else {
if ( ((i + 1) % 4) == 0) {
resultstr += x.substring(i, i + 1) + "|";
} else {
resultstr += x.substring(i, i + 1) + ",";
}
}
i++;
}
return resultstr;
}
Haven't got Java installed but tested the concept via PHP-code:
function matrixFormatter($x) {
$resultstr = "";
$i = 0;
while($i < strlen($x)) {
if ($i == strlen($x) - 1) {
$resultstr .= $x[$i];
} else {
if ( (($i + 1) % 4) == 0) {
$resultstr .= $x[$i] . "|";
} else {
$resultstr .= $x[$i] . ",";
}
}
$i++;
}
return $resultstr;
}
matrixFormatter("abcdefghijklmnopq") returns "a,b,c,d|e,f,g,h|i,j,k,l|m,n,o,p|q".
I'm not sure I understand you question correctly, you should probably add some input and expected output to be more clearer.
String a = "abcdefghijklmnop";
String a2 = "";
for (int i = 0; i < a.length(); i++) {
if (i != 0) {
if(i % 4 == 0){
a2 += "|";
} else{
a2 += ",";
}
}
a2 += a.charAt(i);
}
System.out.println(a2);
This will produce the output a,b,c,d|e,f,g,h|i,j,k,l|m,n,o,p
I'm trying to implement String method contains() without using the built-in contains() method.
Here is what I have so far:
public static boolean containsCS(String str, CharSequence cs) {
char[] chs = str.toCharArray();
int i=0,j=chs.length-1,k=0,l=cs.length();
//String str = "Hello Java";
// 0123456789
//CharSequence cs = "llo";
while(i<j) {
if(str.charAt(i)!=cs.charAt(k)) {
i++;
}
if(str.charAt(i)==cs.charAt(k)) {
}
}
return false;
}
I was just practicing my algorithm skills and got stuck.
Any advice?
Using Only 1 Loop
I did some addition to Poran answer and It works totally fine:
public static boolean contains(String main, String Substring) {
boolean flag=false;
if(main==null && main.trim().equals("")) {
return flag;
}
if(Substring==null) {
return flag;
}
char fullstring[]=main.toCharArray();
char sub[]=Substring.toCharArray();
int counter=0;
if(sub.length==0) {
flag=true;
return flag;
}
for(int i=0;i<fullstring.length;i++) {
if(fullstring[i]==sub[counter]) {
counter++;
} else {
counter=0;
}
if(counter==sub.length) {
flag=true;
return flag;
}
}
return flag;
}
This should work fine..I am printing execution to help understand the process.
public static boolean isSubstring(String original, String str){
int counter = 0, oLength = original.length(), sLength = str.length();
char[] orgArray = original.toCharArray(), sArray = str.toCharArray();
for(int i = 0 ; i < oLength; i++){
System.out.println("counter at start of loop " + counter);
System.out.println(String.format("comparing %s with %s", orgArray[i], sArray[counter]));
if(orgArray[i] == sArray[counter]){
counter++;
System.out.println("incrementing counter " + counter);
}else{
//Special case where the character preceding the i'th character is duplicate
if(counter > 0){
i -= counter;
}
counter = 0;
System.out.println("resetting counter " + counter);
}
if(counter == sLength){
return true;
}
}
return false;
}
Hints:
Use a nested loop.
Extracting the chars to an array is probably a bad idea. But if you are going to do it, you ought to use it!
Ignore the suggestion to use fast string search algorithms. They are only fast for large scale searches. (If you look at the code for String.indexOf, it just does a simple search ...)
As JB Nizet suggested, here is the actual code for contains():
2123 public boolean contains(CharSequence s) {
2124 return indexOf(s.toString()) > -1;
2125 }
And here is the code for indexOf():
1732 public int indexOf(String str) {
1733 return indexOf(str, 0);
1734 }
Which leads to:
1752 public int indexOf(String str, int fromIndex) {
1753 return indexOf(value, offset, count,
1754 str.value, str.offset, str.count, fromIndex);
1755 }
Which finally leads to:
1770 static int indexOf(char[] source, int sourceOffset, int sourceCount,
1771 char[] target, int targetOffset, int targetCount,
1772 int fromIndex) {
1773 if (fromIndex >= sourceCount) {
1774 return (targetCount == 0 ? sourceCount : -1);
1775 }
1776 if (fromIndex < 0) {
1777 fromIndex = 0;
1778 }
1779 if (targetCount == 0) {
1780 return fromIndex;
1781 }
1782
1783 char first = target[targetOffset];
1784 int max = sourceOffset + (sourceCount - targetCount);
1785
1786 for (int i = sourceOffset + fromIndex; i <= max; i++) {
1787 /* Look for first character. */
1788 if (source[i] != first) {
1789 while (++i <= max && source[i] != first);
1790 }
1791
1792 /* Found first character, now look at the rest of v2 */
1793 if (i <= max) {
1794 int j = i + 1;
1795 int end = j + targetCount - 1;
1796 for (int k = targetOffset + 1; j < end && source[j] ==
1797 target[k]; j++, k++);
1798
1799 if (j == end) {
1800 /* Found whole string. */
1801 return i - sourceOffset;
1802 }
1803 }
1804 }
1805 return -1;
1806 }
I came up with this:
public static boolean isSubString(String s1, String s2) {
if (s1.length() > s2.length())
return false;
int count = 0;
//Loop until count matches needle length (indicating match) or until we exhaust haystack
for (int j = 0; j < s2.length() && count < s1.length(); ++j) {
if (s1.charAt(count) == s2.charAt(j)) {
++count;
}
else {
//Redo iteration to handle adjacent duplicate char case
if (count > 0)
--j;
//Reset counter
count = 0;
}
}
return (count == s1.length());
}
I have recently stumbled upon this problem, and though I would share an alternative solution. I generate all the sub strings with length of the string we looking for, then push them into a hash set and check if that contains it.
static boolean contains(String a, String b) {
if(a.equalsIgnoreCase(b)) {
return true;
}
Set<String> allSubStrings = new HashSet<>();
int length = b.length();
for(int i=0; i<a.length(); ++i) {
if(i+length <= a.length()) {
String sub = a.substring(i, i + length);
allSubStrings.add(sub);
}
}
return allSubStrings.contains(b);
}
public static boolean contains(String large, String small) {
char[] largeArr = large.toCharArray();
char[] smallArr = small.toCharArray();
if (smallArr.length > largeArr.length)
return false;
for(int i = 0 ; i <= largeArr.length - smallArr.length ; i++) {
boolean result = true ;
for(int j = 0 ; j < smallArr.length ; j++) {
if(largeArr[i+j] != smallArr[j]) {
result = false;
break;
}
result = result && (largeArr[i+j]==smallArr[j]);
}
if(result==true) {return true;}
}
return false;
}
Certainly not the most efficient solution due to the nested loop, but it seems to work pretty well.
private static boolean contains(String s1, String s2) {
if (s1.equals(s2)) return true;
if (s2.length() > s1.length()) return false;
boolean found = false;
for (int i = 0; i < s1.length() - s2.length(); i++) {
found = true;
for (int k = 0; k < s2.length(); k++)
if (i + k < s1.length() && s1.charAt(i + k) != s2.charAt(k)) {
found = false;
break;
}
if (found) return true;
}
return false;
}
It can be done using a single loop.
public boolean StringContains(String full, String part) {
long st = System.currentTimeMillis();
if(full == null || full.trim().equals("")){
return false;
}
if(part == null ){
return false;
}
char[] fullChars = full.toCharArray();
char[] partChars = part.toCharArray();
int fs = fullChars.length;
int ps = partChars.length;
int psi = 0;
if(ps == 0) return true;
for(int i=0; i< fs-1; i++){
if(fullChars[i] == partChars[psi]){
psi++; //Once you encounter the first match, start increasing the counter
}
if(psi == ps) return true;
}
long et = System.currentTimeMillis()- st;
System.out.println("StringContains time taken =" + et);
return false;
}