location and repetition of characters within a string - java

Hi biologist here with a little bit of coding background. my goal is to be able to input a string of characters and the code to be able to tell me how many times they occur and at what location in the string.
so ill be entering a string and i want the location and abundance of sq and tq within the string. with the location being the first character e.g njnsqjjfl sq would be located at postition 4.
This is what ive come up with so far (probably very wrong)
string S = "...";
int counter =0;
for(int i=0; i<s.length; i++){
if(s.charAt (i) == 'sq')}
counter++;})
string S = "...";
int counter =0;
for(int i=0; i<s.length; i++){
if(s.charAt (i) == 'tq')}
counter++;})
any input will help, thankyou

So , you can have multiple occurrences of "sq" and "tq" in your code, so you can have 2 arraylists to save these two separately(or one to save them together).
ArrayList<Integer>sqLocation = new ArrayList<>();
ArrayList<Integer>tqLocation = new ArrayList<>();
for(int i =0;i<s.length()-1;i++){
if(s.charAt(i)=='s' && s.charAt(i+1)=='q'){
sqLocation.add(i);
}
else if(s.charAt(i)=='t' && s.charAt(i+1)=='q'){
tqLocation.add(i);
}
}
System.out.println("No. of times sq occurs = "+sqLocation.size());
System.out.println("Locations ="+sqLocation);
System.out.println("No. of times tq occurs = "+tqLocation.size());
System.out.println("Locations ="+tqLocation);

This can be achieved using regex. Your use case is to count occurrences and position of those occurrences. The method match returns an integer list which is position and count is size of list
Exmaple code
public class RegexTest {
public static List<Integer> match(String text, String regex) {
List<Integer> matchedPos = new ArrayList<>();
Matcher m = Pattern.compile("(?=(" + regex + "))").matcher(text);
while(m.find()) {
matchedPos.add(m.start());
}
return matchedPos;
}
public static void main(String[] args) {
System.out.println(match("sadfsagsqltrtwrttqsqsqsqsqsqs", "sq"));
System.out.println(match("sadfsagsqltrtwrttqksdfngjfngjntqtqtqtqtqtq", "tq"));
}
}

what you want is a HashMap <String, List <Integer>>
this will hold, the String that you are looking for e.g. sq or tq, and a List of the positions that they are at.
You want to loop around using String.indexOf see https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#indexOf(java.lang.String,%20int)
psuedocode being
String contents = "sadfsagsqltrtwrttqksdfngjfngjntqtqtqtqtqtq";
map.add (lookFor, new ArrayList ());
int index = 0;
while ((index = contents.indexOf (lookFor, index)) != -1) {
list = map.get (lookFor);
list.add (index);
}

You should use not charAt but substring to get a part of String.
int count(String s, String target) {
int counter = 0;
int tlen = target.length();
for (int i = tlen; i < s.length(); i++) {
if (s.substring(i - tlen, i).equals(target)) {
counter++;
}
}
return counter;
}
// in some method
count("...", "sq");
count("...", "tq");

Related

Sorting a list of substrings by order they appear in original

I have used a oomparator to sort an array by the length of the substrings. It works well, but is there a way to order the substrings of the same length in the array, ideally in the order they appear in the original string? For example if I sort the substrings of banana I get:
banana, anana, banan, bana, nana, anan... in this order and would like to get: banana, banan, anana, bana, anan, nana... which is the way they originally appear in banana.
How array is filled:
public static String longestRepeated(String line) {
HashMap<String, Integer> subArray = new HashMap<String, Integer>();
String answer = "";
for (int i = 0; i < line.length(); i++) {
for(int j = 1 ; j <= line.length() - i ; j++) {
if (!subArray.containsKey(line.substring(i, i + j))) {
subArray.put(line.substring(i, i + j), i);
}
}
}
answer = subArray.keySet().toString();
answer = answer.replaceAll("\\[", "");
answer = answer.replaceAll("\\]", "");
String[] subs = answer.split(",");
LongestRepeatedSubstring lrs = new LongestRepeatedSubstring(line);
Arrays.sort(subs, lrs);
for (int i = 0 ; i < subs.length; i++) {
subs[i] = subs[i].trim();
}
comparator:
int lineLength;
public int compare(String str1, String str2) {
int dist1 = Math.abs(str1.length() - lineLength);
int dist2 = Math.abs(str2.length() - lineLength);
return dist1 - dist2;
}
public LongestRepeatedSubstring(String line) {
super();
this.lineLength = line.length();
}
Then I use some loops to find the first one that is repeated and not at the same index. The issue occurs on cases where there are multiple repeated substrings in the array of the same length. I need the one the appears in the String first and they appear in the array randomly.
I don't really get what you are asking but I think that what you are trying to say is that if there is a way to campare again inside the comparator. Right? If that is the case here is an example:
public static Comparator<String> CompareBySomeRestrictionAndOtherRestriction = new Comparator<String>(){
public int compare(String s, String p){
if(){//first condition, for example some strings are the same size
//then use some other criteria, for example alphabetical order
}else{
}
}
}
You just have to work your way in how you are managing the comparisons in order to achieve what you want.
It seems that you do not need a comparator: just print all the substrings

Can anybody help me to correct the following code?

Please help me to identify my mistakes in this code. I am new to Java. Excuse me if I have done any mistake. This is one of codingbat java questions. I am getting Timed Out error message for some inputs like "xxxyakyyyakzzz". For some inputs like "yakpak" and "pakyak" this code is working fine.
Question:
Suppose the string "yak" is unlucky. Given a string, return a version where all the "yak" are removed, but the "a" can be any char. The "yak" strings will not overlap.
public String stringYak(String str) {
String result = "";
int yakIndex = str.indexOf("yak");
if (yakIndex == -1)
return str; //there is no yak
//there is at least one yak
//if there are yaks store their indexes in the arraylist
ArrayList<Integer> yakArray = new ArrayList<Integer>();
int length = str.length();
yakIndex = 0;
while (yakIndex < length - 3) {
yakIndex = str.indexOf("yak", yakIndex);
yakArray.add(yakIndex);
yakIndex += 3;
}//all the yak indexes are stored in the arraylist
//iterate through the arraylist. skip the yaks and get non-yak substrings
for(int i = 0; i < length; i++) {
if (yakArray.contains(i))
i = i + 2;
else
result = result + str.charAt(i);
}
return result;
}
Shouldn't you be looking for any three character sequence starting with a 'y' and ending with a 'k'? Like so?
public static String stringYak(String str) {
char[] chars = (str != null) ? str.toCharArray()
: new char[] {};
StringBuilder sb = new StringBuilder();
for (int i = 0; i < chars.length; i++) {
if (chars[i] == 'y' && chars[i + 2] == 'k') { // if we have 'y' and two away is 'k'
// then it's unlucky...
i += 2;
continue; //skip the statement sb.append
} //do not append any pattern like y1k or yak etc
sb.append(chars[i]);
}
return sb.toString();
}
public static void main(String[] args) {
System.out.println(stringYak("1yik2yak3yuk4")); // Remove the "unlucky" strings
// The result will be 1234.
}
It looks like your programming assignment. You need to use regular expressions.
Look at http://www.vogella.com/articles/JavaRegularExpressions/article.html#regex for more information.
Remember, that you can not use contains. Your code maybe something like
result = str.removeall("y\wk")
you can try this
public static String stringYak(String str) {
for (int i = 0; i < str.length(); i++) {
if(str.charAt(i)=='y'){
str=str.replace("yak", "");
}
}
return str;
}

Finding Anagrams with vowels always at the end

I was trying out this question :
Write a function using Recursion to display all anagrams of a string entered by the user, in such a way that all its vowels are located at the end of every anagram. (E.g.: Recursion => Rcrsneuio, cRsnroieu, etc.) Optimize it.
From this site :
http://erwnerve.tripod.com/prog/recursion/magic.htm
This is what i have done :
public static void permute(char[] pre,char[] suff) {
if (isEmpty(suff)) {
//result is a set of string. toString() method will return String representation of the array.
result.add(toString(moveVowelstoEnd(pre)));
return;
}
int sufflen = getLength(suff); //gets the length of the array
for(int i =0;i<sufflen;i++) {
char[] tempPre = pre.clone();
char[] tempSuf = suff.clone();
int nextindex = getNextIndex(pre); //find the next empty spot in the prefix array
tempPre[nextindex] = tempSuf[i];
tempSuf = removeElement(i,tempSuf); //removes the element at i and shifts array to the left
permute(tempPre,tempSuf);
}
}
public static char[] moveVowelstoEnd(char[] input) {
int c = 0;
for(int i =0;i<input.length;i++) {
if(c>=input.length)
break;
char ch = input[i];
if (vowels.contains(ch+"")) {
c++;
int j = i;
for(;j<input.length-1;j++)
input[j] = input[j+1];
input[j]=ch;
i--;
}
}
return input;
}
Last part of the question is 'Optimize it'. I am not sure how to optimize this. can any one help?
Group all the vowels into v
Group all consonants into w
For every pair of anagrams, concat the results

NullPointerException error while trying to remove a string word from an Array in a remove() method

I'm making this method remove() which takes a String word as argument, to delete from a global Array "words", but I keep getting a NullPointerException for some reason I cannot find, been stuck for hours.
Basically I check for if the word is in the first position, else if is in the last position, or else if it is in neither so I check all the array, and add the first half before the position of the word, and then add the second half after the position of the word in the array, as to skip it and "delete it". But I'm getting a NullPointerException in the for loop looking for the position of the word in the array. Code for the method is here:
public void remove(String a){
String[] temp_arr = new String[words.length-1]; // make array with 1 less length for deleted
if(words[0].equals(a)){ // if the word is the first in the array
for(int x=0, z=1; x<temp_arr.length; x++,z++)
temp_arr[x]=words[z];
words = temp_arr;
} else if(words[words.length-1].equals(a)){ // if the word is in the last position of the array
for(int x=0, z=0; x<temp_arr.length; x++,z++)
temp_arr[x] = words[z];
words = temp_arr;
} else{ // if the word is in neither first or last position of array
// THIS IS WHERE the exception is thrown, in this for loop, in the if(words[k].equals(a))
int k=0;
for (; k<words.length; k++){ // find the position of the word to delete
if (words[k].equals(a)) {
break;
}
}
for (int i = 0; i < k-1; i++){ // add first part of array before the word
temp_arr[i] = words[i];
}
for(int c = k, b = k+1; c< temp_arr.length; c++,b++){
temp_arr[c] = words[b];
}
words = temp_arr; // assign the new values to global array
}
}
Also, if theres any suggestions for good coding practice would be appreciated, thanks!
** I can only use Arrays as my data structure for this method.
Modify the condition like this
a.equals(words[0])
because you know the string value a. But dont know what value will come from array. So even null value comes from the array it does allow the null pointer exception.
I run your code and find a few errors, I correct somethings without changing the core idea:
} else { // if the word is in neither first or last position of array
// THIS IS WHERE the exception is thrown, in this for loop.
int k = -1;
for (int i = 0; i < words.length; i++) { // find the position of the word to delete
if (words[i].equals(a)) {
k=i;
break;
}
}
if(k<0)//if not exists
return;
for (int i = 0; i < k /*- 1*/; i++) { // add first part of array before the word
temp_arr[i] = words[i];
}
for (int i = k; i < temp_arr.length; i++) {
temp_arr[i] = words[i+1];
}
words = temp_arr; // assign the new values to global array
}
If the original array could't have null elements I would do like this:
public static String[] remove(String words[] , String a) {
int counter = 0;
for (int i = 0; i < words.length; i++) {
if( a.equals(words[i]) ){
words[i] = null;
counter++;
}
}
if(counter==0){
return words;
}
String[] words2 = new String[words.length - counter];
int i=0;
for (String string : words) {
if(string!=null){
words2[i++]=string;
}
}
return words2;
}
I would do that like this:
public void remove(String a) {
List<String> tmp = new ArrayList<String>();
for (String word : words) {
if ((word != null) && (word.equals(a))) {
continue;
}
tmp.add(word);
}
words = tmp.toArray(new String[]);
}
I have a question for you:
Why oh why are you using an array? You should always use a collection (eg a List) unless you absolutely have to use an array (which is rare indeed).
If it were a List, you wouldn't even need this method, because List has the remove() method that does all this for you!

Java: how do icheck if a certain character is within a string, then print out the position it is in relative to the string?

What I am trying to do, is create a method, that has a string and a character as parameters, the method then takes the string and searches for the given character. If the string contains that character, it returns an array of integers of where the character showed up. Here is what I have so far:
public class Sheet {
public static void main(String[] args) {
String string = "bbnnbb";
String complete = null;
//*******
for(int i = 0; i < string.length(); i++){
complete = StringSearch(string,'n').toString();
}
//********
}
public static int[] StringSearch(String string, char lookfor) {
int[]num = new int[string.length()];
for(int i = 0; i < num.length; i++){
if(string.charAt(i)== lookfor){
num[i] = i;
}
}
return num;
}
}
The method works fine, and returns this:
0
0
2
3
0
0
What I am trying to do, is make those into 1 string so it would look like this "002300".
Is there any possible way of doing this? I have tried to do it in the starred area of the code, but I have had no success.
just do
StringBuffer strBuff = new StringBuffer();
for(int i = 0; i<str.length(); i++)
{
if(str.charAt(i) == reqChar)
{
strBuff.append(str.charAt(i));
}
else
{
strBuff.append('0');
}
}
return str.toString();
Just add the result to the existing string with the += operator
String complete = "";
for(...)
complete += StringSearch(string,'n').toString();
I would just use java's regex library, that way it's more flexible (eg if you want to look for more than just a single character). Plus it's highly optimized.
StringBuilder positions = "";
Pattern pattern = Pattern.compile(string);
Matcher matcher = pattern.matcher(lookfor);
while(matcher.find()){
positions.append(matcher.start());
}
return positions;
Updated with StringBuilder for better practices.
public static String StringSearch(String string, char lookfor) {
StringBuilder sb = new StringBuilder();
for(int i = 0; i < string.length; i++){
if(string.charAt(i) == lookfor)
sb.append(i);
else
sb.append("0");
}
return sb.toString();
}
Then you can just call it once, without a for loop. Not sure why you call it for every character in the string.
complete = StringSearch(string,'n');

Categories