Finding anagram using array list - java

I'm trying to find if two string are anagrams of each other:
void anagram(String a, String b) {
List<Character> bcopy = new ArrayList<Character>();
for (int i = 0; i < b.length(); i++)
bcopy.add(b.charAt(i));
if (b.length() == 0 || a.length() == 0) {
System.out.println("Exit");
} else {
for (int i = 0; i < a.length(); i++) {
char temp = a.charAt(i);
if (bcopy.contains(temp)) {
System.out.println("match found" + temp);
bcopy.remove(temp);
}
for (char j : bcopy) {
System.out.println("Values" + j);
}
}
}
}
I keep getting an out of bounds error at the remove() line. Can someone please tell me how I reach the array bounds when I'm searching by the object availability? What am I missing here?

The problem is you're using the int-argument version of remove() since the char temp is being treated as an int. Here's a workaround:
bcopy.remove(Character.valueOf(temp));
By the way a better way to test for anagrams would be something like:
char[] c1 = a.toCharArray();
char[] c2 = b.toCharArray();
Arrays.sort(c1);
Arrays.sort(c2);
return Arrays.equals(c1, c2); // true -> anagram, false -> not anagram

there is another algorithm which might be more suitable to the task. it computes the letter frequencies for strings of equal lengths.
for simplicity i assume that the set of all characters involved can be represented in one of the common 8 bit codepages.
void anagram(String a, String b) {
int freqa[256], freqb[256];
if (b.length() == 0 || a.length() == 0) {
System.out.println("Exit");
return;
}
for (int i = 0; i < b.length(); i++) {
freqa[(int) a.charAt(i)]++;
freqb[(int) b.charAt(i)]++;
}
for (i = 0; i < 256; i++) {
if (freqa[i] <> freqb[i]) {
System.out.println("Exit");
return;
}
}
System.out.println("match found: '" + a + "', '" + b + "'");
}

There is a problem with your code. You are removing the items from a list however the loop is running 'n' times is the string length is 'n'.
So if item is removed from the list and the loop count reaches a number which Index is removed from list it will give the exception. You can keep a count instead of removing the items. I modified your code little bit which is working fine now.
Please check
import java.util.ArrayList;
import java.util.List;
class Anagram{
void anagram(String a, String b) {
List<Character> bcopy = new ArrayList<Character>();
int count=0;
for (int i = 0; i < b.length(); i++)
bcopy.add(b.charAt(i));
if (b.length() == 0 || a.length() != b.length()) {
System.out.println("Two strings are not anagram");
} else {
for (int i = 0; i < a.length(); i++) {
char temp = a.charAt(i);
if (bcopy.contains(temp)) {
//System.out.println("match found" + temp);
//bcopy.remove(temp);-- Here list size was reduced but the loop was constant, because list size is less than a.length() now it was giving error
//System.out.println(c);
count++;
}
}
if(count==a.length()) {
System.out.println("Two strings are anagram");
}
else {
System.out.println("Two strings are not anagram");
}
}
}
}
public class Test1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Anagram a=new Anagram();
a.anagram("abs", "ass");
}
}

Related

Palindrome program debugging

The problem is fixed but I need help with creating a method for one of the pieces of code. Any inputs will be appreciated. I tried using void methods but it didn't work. I have highlighted where i want the code to be a method.
import java.util.*;
public class Finalpal {
public Finalpal() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
String word;
int len, counter = 0;
System.out.println("Enter your word");
word = scan.next();
word = word.toUpperCase();
len = word.length();
char array[] = new char[len];
char reverse[] = new char[len];
for (int i=0; i < len; i++)
{
array[i] = word.charAt(i);
}
for (int j=len-1; j>=0; j--)
{
array[counter] = word.charAt(j);
counter++;
}
// This part needs to be a method
for (int k = 0; k < len; k++)
{
if (array[k] != reverse[k])
{
System.out.println("Not a palindrome");
break;
}
if ((array[k] == reverse[k]) && (k == len -1))
{
System.out.println("It is a palindrome");
}
}
}
}
You are not filling in the reverse array
try
for (int j=len-1; j>=0; j--)
{
reverse[counter] = word.charAt(j);
counter++;
}
You have used array[counter] instead of reverse[counter]. You have never filled reverse array
There is a way of doing this without creating a reversed string to compare to the original...
If I knew the length of the string, I could make a loop that checked the characters on either end to see if they were the same and move inward:
[a] [b] [c] [b] [a]
Loop 0: a = a
Loop 1: b = b
Loop 2: c = c
Result: Palindrome!
Functions you need:
int len = String.length();
char c = String.charAt(int);

[Java]Find duplicate characters in a string without hashmap and set

I have written a Java program to find duplicate characters in a string without Hashmap and set.
Below is the program,
package practice;
public class Duplicate {
public static void main(String[] args) {
String src= "abcad";
char[] srcChar= src.toLowerCase().toCharArray();
int len=srcChar.length;
int j=0;
boolean flag=false;
char ch;
// System.out.println("Length of the String is "+len1);
// System.out.println("Length of the character array is "+len);
int k=0;
for(int i=0;i<len;i++)
{
// System.out.println("i-----> "+i + " and character is "+srcChar[i]);
for(j=0;j<len;j++)
{
// System.out.println("j-----> "+j + " and character is "+srcChar[j]);
if(srcChar[i]==srcChar[j])
{
k++;
}
}
if(k>1)
{
if(srcChar[i]>1)
{
System.out.println("This character "+srcChar[i]+" has repeated "+k+ " time");
}
else
{
System.out.println("There are no characters repeated in the given string");
}
}
k=0;
}
}
}
Output here is:
This character a has repeated 2 time
This character a has repeated 2 time
Here, I want the output like
This character a has repeated 2 time
i.e. not repeating the output twice. Since the character "a" is repeated twice, the output is also repeated twice.
kindly help me to get the output once instead of twice.
Thank you,
class PrintDuplicateCharacter
{
public static void main(String[] args)
{
String str = "HelloJava";
char[] ch = str.toCharArray();
int i=0,j=0;
for(i=0;i<ch.length;i++)
{
int count = 0 ;
for( j = i+1;j<ch.length;j++)
{// 4 6 , 8 , 10
if(ch[i] == ch[j] )
{
count++;
}
}
if(count != 0)
{
System.out.print(str.charAt(i) + " Occured " + count + " time");
}
}
}
}
private static void duplicateChar(String str){
char[] arr1 = str.toUpperCase().toCharArray();
int length = str.length();
int count = 1;
String s = "";
char c1 = '\u0000';
for(int i=0;i<length;i++){
count = 1;
for(int j=i+1;j<length;j++){
if(arr1[i] == arr1[j]){
count++;
c1 = arr1[i];
}
if(j == (length-1) && c1 != '\u0000' && !s.contains(String.valueOf(c1))){
s = s+" "+String.valueOf(c1)+" No of times: "+count+"\n";
}
}
}
System.out.println("\nDuplicate char are:\n"+s);
}
You can make a 2 dimensional array, 2 wide, the source strings height. In this array you store a character when it gets replaced and add one to the amount of times it has been replaced.
Something like(I don't know if these counters are correct):
replacements[j][0] = charAt(j);
replacements[j][1] += 1;
You would have to check if the character you are replacing already exists in this array and you can only print elements of the array if they aren't null.
You print this after the original loop.
All you need to fix is to start the second loop from i instead of 0.
for (int i = 0; i < len; i++) {
for (j = i; j < len; j++) {
...
}
...
}
Imports:
import java.util.ArrayList;
import java.util.List;
Code:
public static void main(String args[]) {
String input = "abcad"; // Input value
char[] chars = input.toLowerCase().toCharArray(); // Creates ArrayList
// of all characters
// in the String
List<Character> charR = new ArrayList<>(); // Creates a List used to
// saving the Characters it
// has saved
List<Integer> valR = new ArrayList<>(); // Creates a List that will
// store how many times a
// character is repeated
for (int i = 0; i < chars.length; i++) { // Loop through items in the
// ArrayList
char c = chars[i]; // Create Character value containing the value of
// the item at the "i" index of the ArrayList
if (charR.contains(c)) { // If the List contains item...
for (int i2 = 0; i2 < charR.size(); i2++) { // Loop through its
// items
if (charR.get(i2).equals(c)) { // If you find a match...
valR.set(i2, valR.get(i2) + 1); // Increase repeated
// value by 1
i2 = charR.size(); // Stop loop
} else { // Else...
i2++; // Increase index by 1
}
}
} else { // Else...
charR.add(c); // Add the Character to the List
valR.add(1); // Add the value 1 to the List (Meaning that the
// Character repeated once)
}
}
for (int i = 0; i < charR.size(); i++) { // Loop through all the items
// in the List
System.out.println("'" + charR.get(i) + "' : " + valR.get(i)); // Display
// what
// the
// character
// is
// and
// how
// many
// times
// it
// was
// repeated
}
}
Output:
'a' : 2
'b' : 1
'c' : 1
'd' : 1
char[] array=value.toCharArray();
int count=0;
char ch;
for(int i=0;i<array.length-1;i++)
{
ch=array[i];
count=1;
if(ch!='#'){
for(int j=i+1;j<array.length;j++)
{
if(ch==array[j]){
count++;
array[j]='#';
}
}
if(count>1)
{
System.out.println("char is " + ch + "count" + count);
}
}
}
You can also solve this problem with this code like :
public static void main(String[] args) {
String src = "abcad";
char[] srcChar = src.toLowerCase().toCharArray();
int len = srcChar.length;
int j = 0;
boolean flag = false;
char ch;
// System.out.println("Length of the String is "+len1);
// System.out.println("Length of the character array is "+len);
int k = 0;
for (int i = 0; i < len; i++) {
// System.out.println("i-----> "+i + " and character is "+srcChar[i]);
for (j = 0 + i; j < len; j++) {
// System.out.println("j-----> "+j + " and character is "+srcChar[j]);
if (srcChar[i] == srcChar[j]) {
k++;
}
}
if (k > 1) {
if (srcChar[i] > 1) {
System.out.println("This character " + srcChar[i] + " has repeated " + k + " time");
} else {
System.out.println("There are no characters repeated in the given string");
}
}
k = 0;
}
}
just we need to start the inner loop with j=0+i ;
for (j = 0 + i; j < len; j++)
This will you can observe above code;

How to return longest sequence of chars in a string in java?

Following is what I end up doing but i did not find right answer.
Example - If I have the sequence "hellloo" the output will be "lll". Please tell me what is wrong?
public class LongestSequenceOfChar {
static String testcase1="hellloo";
public static void main(String[] args) {
LongestSequenceOfChar test = new LongestSequenceOfChar();
String result = test.longestSequenceOfChar(testcase1);
System.out.println(result);
}
public String longestSequenceOfChar(String str){
String result="";
for(int i=0;i<str.length();i++){
char ch=str.charAt(i);
for(int j=i+1;j<str.length();j++){
char ch1=str.charAt(j);
if(ch!=ch1){
continue;
}
result+=ch;
}
}
return result;
}
}
You should have a counter that counts the number of the longest sequence for now. When you find a longer sequence, you should reset result and update the counter accordingly.
However, you can have better solutions:
Have an array of size 26 (the size of the English alphabet). Now you iterate on the String and for each char in it you add 1 in the corresponding cell in the helper array.
Use a HashMap that has the char as a key and the number it appears as the value. If it's a new char you simply put it with 0 value, if it exists, you increment the existing value.
Tip: Use a debugger, it can save your life.
1. Create a HashMap<Character,Integer>.. Integer-->count
2. Start from the beginning of your String.. For each character, check if it is already present in the hashmap
a. If Yes, just increment the count
b. if No, then add the character as key to the Map and set its count value to 1.
If there are three 'l' you only add two and in the next step are two 'l' and you add one of them. Then the same with the two 'o' where you are adding one. You only have to clear the result string when you step to the next letter and before save the result in another variable, but only if its is longer!
public String longestSequenceOfChar(String str){
String interimresult="";
String result=""; //final result
for(int i=0;i<str.length();i++){
char ch=str.charAt(i);
interimresult += ch; //add the letter once
for(int j=i+1;j<str.length();j++){
char ch1=str.charAt(j);
if(ch!=ch1){
break;
}
interimresult +=ch;
}
if(interimresult.length()>result.length())//store the result if it is longer
result = interimresult;
interimresult = ""; //clear to continue with the next letter
}
return result;
}
Here is a solution:
public String longestSequenceOfChar(String str) {
String result = "";
for (int i = 0; i < str.length(); i++) {
int j = i;
while(j < str.length() && str.charAt(j) == str.charAt(i)) {
j++;
}
// If this one is longer than previous, then asign it to result.
if(j - i > result.length()) {
result = str.substring(i, j);
}
}
return result;
}
This can be solved easily using HashMap. Checkout this sample code:
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public class MaximumOccuringCharUsingHashMap {
public static void main(String[] args) {
String test = "test samples";
MaximumOccuringCharUsingHashMap mc =
new MaximumOccuringCharUsingHashMap();
System.out.println( mc.findMaximunOccurenceCharacter(test));
}
char findMaximunOccurenceCharacter(String input){
Map<Character, Integer> countHash =
new HashMap<Character, Integer>();
for(int i=0; i<input.length() ;i++ ){
char currentChar = input.charAt(i);
if(countHash.get(currentChar)==null){
countHash.put(currentChar, 1);
}else{
countHash.
put(currentChar, countHash.get(currentChar)+1);
}
}
int max = Collections.max(countHash.values());
char maxCharacter =0;
for(Entry<Character, Integer> entry :countHash.entrySet()){
if(entry.getValue() == max){
maxCharacter = entry.getKey();
}
}
return maxCharacter;
}
}
Above code will print s as output, which is occurring maximum number of times in the given String.
Try This...
public class HelloWorld {
public static void main(String[] args) {
System.out.println(maxLen(null));
System.out.println(maxLen(""));
System.out.println(maxLen("a"));
System.out.println(maxLen("aa"));
System.out.println(maxLen("abcddd"));
System.out.println(maxLen("abcd"));
System.out.println(maxLen("aabbba"));
}
public static String maxLen(String input) {
// Avoid NPEs
if (input == null) {
return null;
}
int maxLen = 0;
int tempLen = 0;
char prevChar = 0;
char c = 0;
char repeatChar = 0;
for (int i = 0; i < input.length(); i++) {
c = input.charAt(i);
if (c == prevChar) {
tempLen++;
if (tempLen > maxLen)
repeatChar = c;
} else {
maxLen = (tempLen > maxLen) ? tempLen : maxLen;
prevChar = c;
tempLen = 1;
}
}
maxLen = (tempLen > maxLen) ? tempLen : maxLen;
if (maxLen == 0 || maxLen == 1)
return "no sequence found";
else {
String str = "";
for (int i = 1; i <= maxLen; i++)
str += String.valueOf(repeatChar);
return str;
}
}
}
This will pass all test cases.

String Compression loop logic

My for loop for my string compression is a bit off. I have been working on this assignment the past 5 days and I can't figure out for the life of me what is wrong. Can someone help me out?
For example, I passed over the string "TTTTrrrEe" and instead of getting T4r3Ee, I'm getting T4r3EeTT. I don't know why it jumps back to the beginning of the string like that, but I am getting closer.We can only use charAt,equals,length, and substring from the string class.
Can someone help guide me in the right direction by helping to correct my logic? I still want to try and code this myself, seeing as how it is an assignment.
public static String compress(String s){
int count = 0;
String temp = s.substring(0,1);
for(int i = 0; i < s.length(); i++){
if(i !=s.length()-1){
if(temp.equals(s.substring(i,i+1))){
count++;
}else{
if(count < 1){
System.out.print(s.substring(i,i+2));
System.out.print(temp.substring(0,1) );
}else{
System.out.print("" + temp.substring(0,1) + count);
i--;
temp = s.substring(count,count+1);
System.out.println(" temp is now " + temp);
count = 0;
//i--;
}
}
}
}
System.out.println(temp);
return temp;
}
Since this is a learning exercise, I wouldn't try fixing your code, just point out a few things to work on to get it right:
The if (i !=s.length()-1) condition inside the loop becomes unnecessary if you change your for loop condition to i < s.length()-1
Comparing individual characters is easier (and faster) than comparing substrings. You get a character at position i by calling char ch1 = s.charAt(i), and compare two characters using == operator, rather than calling equals() on them.
When count is zero (your count < 1 condition is equivalent to count == 0) you print both the current character and the character after it, in addition to the first character of temp followed by the count. This does not look correct.
Rather than growing temp as you go through the loop, you set it on each iteration. This does not look correct.
A better way of growing temp as you go through the loop is using StringBuilder and append(), instead of using a plain String, and performing concatenations.
Try using some logic like this;
int count = 0;
for(int i =0; i < string.length()-1; i++){
if(string.charAt(i) == string.charAt(i + 1)){
count++;
// DO SOME OPERATION
}
}
temp = s.substring(count,count+1); does not relate to a position (i), but a size.
In fact I would try to rewrite it afresh, with externally sensible names:
char repeatedChar = `\u0000`; // Not present.
int repetitions = 0;
Because of the no-namer count you got into trouble.
Working code:
public class HelloWorld {
public static void compress(String s){
StringBuilder buff = new StringBuilder();
char tmp = '\0';
int index = 1;
for(int i = 0; i < s.length(); i++){
char curr = s.charAt(i);
if(buff.length() == 0){
tmp = curr;
buff.append(tmp);
continue;
}
if(curr == tmp){
index++;
}
else{
if(index > 1){
buff.append(index);
index = 1;
tmp = curr;
}
buff.append(curr);
}
}
System.out.println(buff.toString());
}
public static void main(String args[]){
compress("TTTTrrrEe");
}
}
Output: T4r3Ee
For compress("TTsssssssssssTTrrrEe");
Output: T2s11T2r3Ee
String temp = s.substring(0,1);
temp.equals(s.substring(i,i+1))
In case of these 2 sentences you should have used a char instead of String, as such:
char temp = s.charAt(0)
temp == s.charAt(i)
I would start with 3 variables:
char lastCharacter = inputString.charAt(0);
int count = 1;
String result = "";
then proceed to process the input string in a loop:
if (length <= 1) return inputString;
for i = 1 ; i < length;i++
if (inputString.charAt(i) == lastCharacter && i != length-1)
count++
else
if count == 1
result += lastCharacter
else
result = result + lastCharacter + count;
count = 1;
end if
lastCharacter = inputString.charAt(i);
end if
end for
return result;
TRY THIS
public class Compress {
/**
* #param args
* #author Rakesh KR
*/
public static String encode(String source) {
StringBuffer dest = new StringBuffer();
for (int i = 0; i < source.length(); i++) {
int runLength = 1;
while (i+1 < source.length() && source.charAt(i) == source.charAt(i+1)) {
runLength++;
i++;
}
dest.append(source.charAt(i));
dest.append(runLength);
}
return dest.toString();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
String example = "aaaaaaBBBBccc";
System.out.println("Encode::"+encode(example));
}
}

count specific characters in a string (Java)

I have a homework assignment to count specific chars in string.
For example: string = "America"
The output should be = a appear 2 times, m appear 1 time, e appear 1 time, r appear 1 time, i appear 1 time and c appear 1 time
public class switchbobo {
/**
* #param args
*/ // TODO Auto-generated method stub
public static void main(String[] args){
String s = "BUNANA";
String lower = s.toLowerCase();
char[] c = lower.toCharArray(); // converting to a char array
int freq =0, freq2 = 0,freq3 = 0,freq4=0,freq5 = 0;
for(int i = 0; i< c.length;i++) {
if(c[i]=='a') // looking for 'a' only
freq++;
if(c[i]=='b')
freq2++;
if (c[i]=='c') {
freq3++;
}
if (c[i]=='d') {
freq4++;
}
}
System.out.println("Total chars "+c.length);
if (freq > 0) {
System.out.println("Number of 'a' are "+freq);
}
}
}
code above is what I have done, but I think it is not make sense to have 26 variables (one for each letter). Do you guys have alternative result?
Obviously your intuition of having a variable for each letter is correct.
The problem is that you don't have any automated way to do the same work on different variables, you don't have any trivial syntax which helps you doing the same work (counting a single char frequency) for 26 different variables.
So what could you do? I'll hint you toward two solutions:
you can use an array (but you will have to find a way to map character a-z to indices 0-25, which is somehow trivial is you reason about ASCII encoding)
you can use a HashMap<Character, Integer> which is an associative container that, in this situation, allows you to have numbers mapped to specific characters so it perfectly fits your needs
You can use HashMap of Character key and Integer value.
HashMap<Character,Integer>
iterate through the string
-if the character exists in the map get the Integer value and increment it.
-if not then insert it to map and set the integer value for 0
This is a pseudo code and you have to try coding it
I am using a HashMap for the solution.
import java.util.*;
public class Sample2 {
/**
* #param args
*/
public static void main(String[] args)
{
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
String test = "BUNANA";
char[] chars = test.toCharArray();
for(int i=0; i<chars.length;i++)
{
if(!map.containsKey(chars[i]))
{
map.put(chars[i], 1);
}
map.put(chars[i], map.get(chars[i])+1);
}
System.out.println(map.toString());
}
}
Produced Output -
{U=2, A=3, B=2, N=3}
In continuation to Jack's answer the following code could be your solution. It uses the an array to store the frequency of characters.
public class SwitchBobo
{
public static void main(String[] args)
{
String s = "BUNANA";
String lower = s.toLowerCase();
char[] c = lower.toCharArray();
int[] freq = new int[26];
for(int i = 0; i< c.length;i++)
{
if(c[i] <= 122)
{
if(c[i] >= 97)
{
freq[(c[i]-97)]++;
}
}
}
System.out.println("Total chars " + c.length);
for(int i = 0; i < 26; i++)
{
if(freq[i] != 0)
System.out.println(((char)(i+97)) + "\t" + freq[i]);
}
}
}
It will give the following output:
Total chars 6
a 2
b 1
n 2
u 1
int a[]=new int[26];//default with count as 0
for each chars at string
if (String having uppercase)
a[chars-'A' ]++
if lowercase
then a[chars-'a']++
public class TestCharCount {
public static void main(String args[]) {
String s = "america";
int len = s.length();
char[] c = s.toCharArray();
int ct = 0;
for (int i = 0; i < len; i++) {
ct = 1;
for (int j = i + 1; j < len; j++) {
if (c[i] == ' ')
break;
if (c[i] == c[j]) {
ct++;
c[j] = ' ';
}
}
if (c[i] != ' ')
System.out.println("number of occurance(s) of " + c[i] + ":"
+ ct);
}
}
}
maybe you can use this
public static int CountInstanceOfChar(String text, char character ) {
char[] listOfChars = text.toCharArray();
int total = 0 ;
for(int charIndex = 0 ; charIndex < listOfChars.length ; charIndex++)
if(listOfChars[charIndex] == character)
total++;
return total;
}
for example:
String text = "america";
char charToFind = 'a';
System.out.println(charToFind +" appear " + CountInstanceOfChar(text,charToFind) +" times");
Count char 'l' in the string.
String test = "Hello";
int count=0;
for(int i=0;i<test.length();i++){
if(test.charAt(i)== 'l'){
count++;
}
}
or
int count= StringUtils.countMatches("Hello", "l");

Categories

Resources