I have a char array filled by the user (arrayInput[]) with some characters, like {b, d, a, b, f, a, g, a, a, f}, and I need to create a method which returns a new char array with only the first occurrence of the character, but in the order of input. The book also says "A way to solve this problem is to create a boolean array to keep track of the characters to mantain!", but I can't imagine how the boolean array should work with the other arrays.
The main problem is that I can save in a boolean array if arrayInput contains a specific character, and even how many times, but only creating a very long ramified if-else into a for, like
if ((arrayOutput[i] == 'A') && (arrayControl[0] = false)) {
arrayControl[0] = true; }
where arrayOutput is the array I want to return from the method, arrayControl[0] is the value of 'A' in my boolean array I created into the method. A = 0, B = 1, ... Z = 25, a = 26, b = 27, ... 51 = z. For every single character, uppercase and lowercase, I created a place into the array, so I could check everything, but now I can't go any further. I don't know how to save the characters on arrayOutput, how to check if a character is already on arrayOutput and if it's already there, the array passes that specific character and go to the next one.
Also please remember I'm a newbie, so I know very little about Java. Please explain yourself the best you can. Thanks in advance!
This could work:
public static void main(String[] args) {
Main main = new Main();
char[] array = {'e','a','b','a','c','d','b','d','c','e'};
main.getCharArray(array);
}
private char[] getCharArray(char[] array) {
String _array = "";
for(int i = 0; i < array.length; i++) {
if(_array.indexOf(array[i]) == -1) // check if a char already exist, if not exist then return -1
_array = _array+array[i]; // add new char
}
return _array.toCharArray();
}
Output:
eabcd
boolean arr[26]; //considering only small letters arrive. otherwise take a larger array.
for( i=0;i<str.length;i++ )
arr[str[i]-'a']=true;
The ones at last after the loop are true are the actual character. (all duplicates eleminated).
To take into consideration the positions,
int arr[26];
//initialize all the array elemnts to 0
for( i=0;i<str.length();i++ )
if(i>=arr[str[i]-'a'])
arr[str[i]-'a']=i+1;
//Those greater than 0 are non-duplicated characters. Their poistion of first occurence= (arr[i]-1)
EDIT: I have last used java almost a year ago. The algorithm is shown properly. Sorry for my awkward java code.
This might help. Make a separate array and store only non-duplicate characters.
char[] removeDuplicates (char[] arrayInput) {
boolean exists[]=new boolean[26];
char arrayOutput[] = new char[26];
int ctr=0;
for(int i=0; i<26; i++) {
exists[i] = false;
}
for(int i=0; i<arrayInput.length; i++) {
if(!exists[arrayInput[i]-97]) {
exists[arrayInput[i]-97]=true;
arrayOutput[ctr++]=arrayInput[i];
}
}
return Arrays.copyOfRange(arrayOutput, 0, ctr);
}
If you consider using of collection framework then it would be much easier. Your array of char with duplicate is arrayInput. Now put each char from it to a HashSet like this -
HashSet<Character> uniqueCharSet = new HashSet<Character>();
for(char each : arrayInput){
uniqueCharSet.add(each);
}
Now the HashSet uniqueCharSet will contains only the unique characters from the char array arrayInput. Note here all element in uniqueCharSet are wrapper type - Character.
You can convert the HashSet uniqueCharSet to array of Character like this -
Object[] uniqueCharArray = uniqueCharSet.toArray();
And then you can use them like this -
for(Object each : uniqueCharArray){
Character c = (Character) each;
System.out.println(c);
}
Here's the method to achieve what you need:
public static void main(String[] args) {
char[] arr= {'A','B','C','A','B'};
HashSet<Character> hset=new HashSet<Character>();
for(int i=0;i<arr.length;i++) {
hset.add(arr[i]);
}
Object[] ObjChar=hset.toArray();
char[] resultArr = new char[ObjChar.length];
for(int j=0;j<ObjChar.length;j++) {
resultArr[j]=(char) ObjChar[j];
}
for(char eachChar: resultArr) {
System.out.println(eachChar);
}
}
Related
I am required to write up a static method named getSuccessiveLetters(words) that takes a string array and returns a single String. If the String array is {"hello", "world"}, then the program should return "ho". "h" is from the first word, "o" is the 2nd letter from the 2nd word and so on.
I managed to get the correct return value for {"hello", "world"}, but if the String array contains, for example,{"1st", "2nd", "3rd", "4th", "fifth"} it goes out of range it struggles.
public class Template01 {
public static void main(String[] args) {
System.out.println(getSuccessiveLetters(new String[]{"1st", "2nd", "3rd", "4th", "fifth"}));
}
public static String getSuccessiveLetters(String[] words) {
char Str[] = new char[words.length];
String successive;
for(int i = 0; i < words.length; i++){
successive = words[i];
if (i < successive.length()){
Str[i] = successive.charAt(i);
}
else
{
break;
}
}
successive = new String(Str);
return successive;
}
I expected the return value to be 1nd, but the actual output is 1nd\x00\x00.
This is happening because when you initialize a char array, it fills the array with the default char value.
You can use StringBuilder or List<Character> to grow your "array" with each addition.
Change
char[] str = new char[words.length];
to
StringBuilder str = new StringBuilder();
and
str[i] = successive.charAt(i);
to
str.append(successive.charAt(i));
and then at the end successive = str.toString();.
This is because when you ignore the strings in the original array that are not long enough, you are not setting some of the char array elements as a result. This means that some elements will have the char value of \0 (default value of char). The resulting string therefore has these extra \0 characters as well.
I think it is more suitable to use a StringBuilder rather than a char[] here:
public static String getSuccessiveLetters(String[] words) {
StringBuilder builder = new StringBuilder();
String successive;
for(int i = 0; i < words.length; i++){
successive = words[i];
if (i < successive.length()){
builder.append(successive.charAt(i));
}
// you should not break here, because there might be a longer string in the array later on.
// but apparently you don't want the "h" in "fifth"? Then I guess you should break here.
}
successive = builder.toString();
return successive;
}
I recommend using Unit-Tests here. This could help you to improve.
you are creating a charArray here:
char Str[] = new char[words.length];
this array has the length of your string-array
new String[]{"1st", "2nd", "3rd", "4th", "fifth"}
which is 5
you create 3 entries for your new array (because you break at the first word, which is too short)
therefor you get 3 letters "1nd" and the 2 other slots in your array are filled with blanks when calling
successive = new String(Str);
1st: think about the break statement
2nd: think about using a StringBuilder / StringBuffer instead of a char[] for your matches
imho the most correct result should be 1nd h - but this depends on your given task
I want the user to input a string, then I want to check if each charachter in this string exists in an array of charachters I created. Even if it's not in the correct order.
The way I go about it is initialise the array of chars then through using the scanner have a String input from the user.
public static char[]aa={'A','C','D','E','F','G','H','I','K','L','M','N','P','Q','R','S','T','V','W','Y','U','O','B','J','Z','X'};
I created a function
private static void isValidSequence(String sequence, char[] k) {
outter :for (int j = 0; j < sequence.length(); j++) {
for (int i = 0; i < k.length; i++) {
if(sequence.charAt(j) == k[i]){
break;
} else {
System.out.println("invalid");
break outter;
}
}
}
}
What happens is that if for example the first letter of the the string doesn't match the first input of array it gives me an 'invalid' input. How can I go around that? and make it iterate through the whole array of characters before giving the invalid output.
An approach would be to sort your array, and then use the Binary Search Algorithm (BSA):
// sort the array once
Arrays.sort(aa);
// iterate over the input string
for(int i = 0, length = sequence.length(); i < length; i++) {
// the java implementation of the BSA returns negative numbers for not found elements
if(Arrays.binarySearch(aa, sequence.charAt(i)) < 0) {
// char was not found, break loop
return;
}
}
Note: If the array is not sorted / can not be sorted, then the BSA is useless and will produce undefined results.
Note 2: The BSA is faster (O(log n)) than simple iteration (O(n))
This can also be done as below :
char[]aa={'A','C','D','E','F','G','H','I','K','L','M','N','P','Q','R','S','T','V','W','Y','U','O','B','J','Z','X'};
String s = "aStrinG";
for (char c : s.toCharArray()) {
for (char c2 : aa) {
if (c2 == c) {
System.out.println("String char " + c + " exists in char array");
}
}
}
It produces :
String char S exists in char array
String char G exists in char array
Best way is to use SET instead of an Array. A set contains no duplicate elements and then simply you can use it using the method contains()
Using Java 9 (Unmodifiable Sets)
Set<Character> alphabetSet = Set.of('A', 'B', 'C');
//Another way
//Set<Character> alphabetSet = new HashSet<>(Arrays.asList('A', 'B', 'C'));
for(char c: sequence)
{
if(alphabetSet.contains(c)){
//do something
}
else{
//do something
}
}
Read more about Set:
https://docs.oracle.com/javase/7/docs/api/java/util/Set.html
To directly answer your question:
Solution 1:
Use continue instead of break this will print "invalid" each time a character is not in k.
Solution 2:
You can use a counter and increment it every time you have a character not in k, then outside the loop you will have visibility on how many invalid characters you have.
Solution 3:
If you want even more detail you can have a list of characters and add each invalid character to this list. This will give you visibility on exactly what characters are invalid.
I am not sure what you are trying to do so I don't know which method is better for you, you can also use an altogether approach using streams for example.
If you start using the Collection provided, you could use a Set to do your checks.
First, convert the array into the Set :
char[] array = "abcdefghijklmnopqrstuvwxyz".toCharArray();
Set<Character> setAllowed = new TreeSet<>();
for(char c : array){
setAllowed.add(c);
}
Then, you just have to iterate and check for each character. I would add another Set to retrieve every characters not allowed, giving a better output.
Set<Character> setError = new TreeSet<>();
for(char c : s.toCharArray()){
if(setAllowed.contains(c)){
setError.add(c);
}
}
Test :
public static void main(String[] args) {
String s = "foobar123";
char[] array = "abcdefghijklmnopqrstuvwxyz".toCharArray();
//INIT
Set<Character> setAllowed = new TreeSet<>();
Set<Character> setError = new TreeSet<>();
for(char c : array){
setAllowed .add(c);
}
//RESEARCH
for(char c : s.toCharArray()){
if(setAllowed.contains(c)){
setError.add(c);
}
}
//OUTPUT
System.out.println(setError);
}
[1, 2, 3]
I'm working on an a problem trying to generate all the possible combination between two chars based on early generated combine using java 8
for example :
private static final String LETTER_RANGE = "abcdefghijklmnopqrstuvwxz";
from this letter rang I want to extract all differents combine between two chars XX
for example :
zz,zx,zw....za
xz,xx,xw....xa
..,..,..,..,..
az,ax,aw... aa
My problem is I need to generate those combination at runtime based on previous combine :
String value = generate("zx") // this should return 'zw'
Can any one helpe me on any idea how can use java 8 loops,Stream,String to do this Thanks in advance
You can use simple character arithmetics. As chars can be incremented and compared:
final List<String> permutations = new ArrayList<>(26 * 26);
for (char[] array = {'a', 'a'}; array[0] <= 'z'; array[0]++) {
for (array[1] = 'a'; array[1] <= 'z'; array[1]++) {
permutations.add(new String(array));
}
}
This piece of code creates every combination of all characters between a and z inclusive and adds them to a List.
This is possible because in ASCII the character value of a (97) is smaller than the one from z (122).
I've also used some optimizations, like the use of an array inside the for-loop to hold the current combination of 2 chars. This array can then also be directly used to create a new string, with the string constructor: String(char[]).
Tools one might use are:
char ch = LETTER_RANGE.charAt(2); // 'c'
int ix = LETTER_RANGE.indexOf(ch); // 2
Using the single char[] array is probably much easier, so the method might look like:
String next(String combination) {
char[] chars = combination.toCharArray();
char ch = chars[1];
if (...) {
}
return new String(chars);
}
Sounds like very bad solution of task for me. But if you really need it, it can be done like this.
private static final String LETTER_RANGE = "abcdefghijklmnopqrstuvwxz";
public String findNext(String prev) {
if(prev==null || prev.length()<2)
throw new RuntimeException("Invalid argument");
int char1Index = LETTER_RANGE.indexOf(prev.charAt(0));
int char2Index = LETTER_RANGE.indexOf(prev.charAt(1));
char2Index--;
if (char2Index < 0) {
char1Index--;
char2Index = LETTER_RANGE.length() - 1;
}
if (char1Index < 0) {
return null;// or what you need here.
}
return new String(new char[]{LETTER_RANGE.charAt(char1Index), LETTER_RANGE.charAt(char2Index)});
}
And the task find all Concatenation between two chars from predefined list I would do like this
public List findAll() {
List<String> result=new ArrayList<>();
char[] chars=LETTER_RANGE.toCharArray();
for(int i=0;i<chars.length;i++)
for(int j=0;j<chars.length;j++)
result.add(new String(new char[]{chars[i],chars[j]}));
return result;
}
The pattern in your example reminds me of Excel columns. Excel names its columns with letters from A to Z, and then the sequence goes AA, AB, AC... AZ, BA, BB, etc. So if we interpret your combinations as Excel column titles the task could be reworded to:
Given a column title as appears in an Excel sheet, find the next
column title (or previous as shown in your expected output).
To do this you can write a method that accepts a string as a parameter (like "zf") and returns the actual column number. And then add or substract 1 to get the number of the next or previos column and convert the number back to string. Example:
public final class ExcelColumn {
public static void main(String[] args) {
String str = "zx";
System.out.println(getPreviousColumn(str));
}
public static int toColumnNumber(String column) {
int result = 0;
for (int i = 0; i < column.length(); i++) {
result *= 26;
result += column.charAt(i) - 'a' + 1;
}
return result;
}
public static String toColumnName(int number) {
final StringBuilder sb = new StringBuilder();
int num = number - 1;
while (num >= 0) {
int numChar = (num % 26) + 97;
sb.append((char)numChar);
num = (num / 26) - 1;
}
return sb.reverse().toString();
}
public static String getNextColumn(String s) {
return toColumnName( toColumnNumber(s)+1);
}
public static String getPreviousColumn(String s) {
return toColumnName( toColumnNumber(s)-1);
}
}
ToDo:
Input validiation and
exception handling
Pros:
You can use this even if your combined string length is > 2
can be easily modified to use with uppercase letters
You can do something like from 'be' to 'cf' to generate all combinations which fall in this range if necessary
Cons:
May be to much code for a simple task. Look at #Andrii Vdovychenko's
comment which solves the problem in few lines
So i have been trying to make a code that counts the number of words in a string which was pretty easy. I'm running into problems when im trying to make it count the number of unique characters in a string. The program compiles and runs it doesn't display the number of Unique characters. Adding a System.out.println(countOfUniqueChars); below return doesn't work.
Here's the code:
public class Uniquechar{
public static void main(String[] args) {
String s = "Jag vet inte vad jag heter idag";
String[] parts = s.split(" ");
int wordcount = parts.length;
System.out.println("The number of words is" + wordcount);
countUniqueCharacters(s);
}
public static int countUniqueCharacters(String s) {
String lowerCase = s.toLowerCase();
char characters[] = lowerCase.toCharArray();
int countOfUniqueChars = s.length();
for (int i = 0; i < characters.length; i++) {
if (i != lowerCase.indexOf(characters[i])) {
countOfUniqueChars--;
}
}
return countOfUniqueChars;
}
Try this:
s = s.replace(" ", ""); // If you don't want to count space
char[] chars = s.toCharArray();
Set<Character> uniqueChars = new HashSet<>();
for (char c : chars) {
uniqueChars.add(c);
}
System.out.println(c.size());
Just print the method call, it prints the result.
System.out.println(countUniqueCharacters(s));
Adding a System.out.println(countOfUniqueChars); below return doesn't work.
It won't work. Because the code after return statement is unreachable. Perhaps you can do it just before return.
System.out.println(countOfUniqueChars);
return countOfUniqueChars;
You can do System.out.println(countUniqueCharacters(s)); in the main method, to output the return value of your method. After a return, you cannot add more code. I did it for you and the output is 12, so it seems to be that there is also something wrong with your algorithm.
int uniqeCharsCount = countUniqueCharacters(s);
System.out.println("The number of uniqe chars is " + uniqeCharsCount);
Output: 12
Your algorithm:
Actually you are checking every char, if this char is one more time in the string before. But you should also check if the char is anywhere in the string after the current index. You can fix it if you change your if condition to if (i != lowerCase.indexOf(characters[i]) || i != lowerCase.lastIndexOf(characters[i]))
Output of the fixed version: 3 (n, h, r)
I would recommend using a Set to retain only uniques, then count its size, instead of iterating:
public static int countUniqueCharacters(String s) {
String lowerCase = s.toLowerCase();
char characters[] = lowerCase.toCharArray();
Set<Character> uniques = new HashSet<Character>();
for (char c: characters) {
uniques.add(c);
}
return uniques.size();
}
if (i != lowerCase.indexOf(characters[i])) {
countOfUniqueChars--;
}
This is wrong. Your lowerCase string is lowercase, so any uppercase letters in characters[i] will have an index of -1 in lowerCase (will be calculated as a non-unique character). You can fix this by using indexOf(lowerCase.charAt(i));
A good way to count the number of characters would be eliminating repetitions. The ideia is get the first character, then find next occurrences and replace by nothing, once you do that you can count the unique characters.
public static int countUniqueCharacters(String s) {
String lowerCase = s.toLowerCase();
///Get the first char of lowerCase
String firstChar = lowerCase.substring(0,1);
//Take off the first char
String subS = lowerCase.substring(1);
///replace all chars equals to first char
String replacedSubS = subS.replace(firstChar, "");
/// Now, call method again to calculate size
/// of the substring with first char
// replaced by blank char
return 1+countUniqueCharacters(replacedSubS);
}
This method worked for me, take a look. You may do that in two lines, but i thought it's better be detailed here.
Adding a System.out.println(countOfUniqueChars); below return doesn't work.
That is expected behavior because return means that flow of control will be returned from method to place where this method was invoked. This means that code after return will not be executed, so in situation like
return countOfUniqueChars;
System.out.println(countOfUniqueChars);
System.out.println(countOfUniqueChars); would be dead code.
You could try printing value before you return it like
System.out.println(countOfUniqueChars);
return countOfUniqueChars;
or simply print returned value in main method like
int count = countUniqueCharacters(s);
System.out.println(count);
or using this one-liner
System.out.println(countUniqueCharacters(s));
BTW since Java 8 your code can look like
s.toLowerCase().chars().distinct().summaryStatistics().getCount()
or if you want to skip spaces you can add
s.toLowerCase().replace(" ","").chars().distinct().summaryStatistics().getCount()
public static int countUniqueCharacters(String s) {
char [] input=s.toCharArray();
Set<Character> charset=new HashSet<>();
for (int i = 0; i < input.length; i++) {
charset.add(input[i]);
}
return charset.size();
}
// My code is doing something; difficult to get.. still a concept can be grasped.
//I am having my method (searchCity) in class graph. this method is called from main
//class and is yes... selecting one array by charachter it is passed with
public class graph {
int a = 1000;
int flag = 0;
//array of all cities having elements as connection to other cities
public graph(){
char [] i = {'i','v'};
char [] v = {'v','u'};
char [] u = {'u','b','h'};
char [] b = {'b','p','f','u'};
char [] h = {'h','u','e'};
char [] e = {'e','h'};
char [] p = {'p','b','r','c'};
char [] c = {'c','p'};
char [] r = {'r','s','p'};
char [] s = {'s','f','r'};
char [] f = {'f','s','b'};
}
public void searchCity( char i, char j){
// check for equal array as parameter i (include must )
for (int z = 0 ; z < i.length; z ++) {
if (i[z] == 'j') {
int ascii = (int) 'j';
int flag = 1;
System.out.println(ascii);
}
else {
// checking for smallest cost in the complete array
int ascii = (int) i[z];
if(a>ascii)
a=ascii;
else continue;
}
}
if (flag==0){
char b = (char) a;
char [] c = {'b'};
}
searchCity(c, j);
}
I have a class with many arrays named in alphabets like char [] a, char [] b etc. I also have a method in class.
In main class I have created an object and if i need to pass two alphabets which will be like reference for calling only those arrays whose name are passed.
like my line of code in main class is as follows:
object.function(char1, char2);
these characters will be alphabets(a,b,c etc) can it be done ?? how ?? please help. I searched it but exact problem is not answered.. Regards
If you are asking how to pass char arrays to a function, all you need to do is set up your function as follows:
public static void MyFunction(char[] a, char[] b) {
//do stuff to char arrays
}
Then when you call the function, you will be able to pass them in with:
char[] a = {'a', 'b', 'c'};
char[] b = {'d', 'e', 'f'};
MyObject.MyFunction(a, b);
It would be helpful if you posted your current code so I can tell exactly what it is you're trying to do, though.
EDIT:
If you want to be able to call the arrays with a char, I'd suggest containing them in a HashMap:
Map<Character, Character[]> graph = new HashMap<Character, Character[]>();
graph.put('i', new Character[] {'i', 'v'});
graph.put('v', new Character[] {'v', 'u'});
graph.put('u', new Character[] {'u', 'b', 'h'});
// etc.
Then you can call the arrays as follows:
System.out.println(graph.get('i')[0]); // Prints 'i'
System.out.println(graph.get('i')[1]); // Prints 'v'
System.out.println(graph.get('i').length); // Prints '2'
So a function could be something like this:
public static void MyFunction(char a, char b) {
graph.get(a)[0]; // grab first character in array
for (int i=0; i<graph.get(b).length; i++) {
// recursively go through array with graph.get(b)[i]
}
}
Demonstration Here
Hope this helps.
I found your question kind of confusing, so if I am way off, please tell me.
However, what I think your trying to do is is call a char array with a character. For instance calling the char array c with the character 'a'. You can do this with if conditionals of switches. Also, what does your object.function(char1, char2) actually do? That would help me out in answering you question.