How to reverse a SoundSample array? - java

I have to reverse the order of an array called myWordArray that plays from a thisisatest.wav file. It should play "test a is this" instead of "this is a test."
public void playReverseOrder(int pause) throws InterruptedException {
Sound orig = new Sound();
int length = myWordArray.length;
for (int i = 0, source = length - 1; i < length && source > 0; i++, source--) {
myWordArray[i].setSampleValueAt(i, orig.getSampleValueAt(source));
myWordArray[i].blockingPlay();
Thread.sleep(pause);
}
}
My logic is that I create a new sound, then use the length to increment the index i forward as the original source decrements. It plays forward, however I cannot get the words to reverse. I've thought of retrieving the samples of the myWordArray within new Sound (myWordArray.getSamples()); however that does not work, and I would try to access the file within the parameters, but we select the file manually within the test harness.

I am assuming, you meant test a is this. This is a harder problem and discussed below. If you want to make it sound like tset a si siht, you can simply arrange the content of the array in reverse order. Please note that, this sound wont be intelligible.
myWordArray[i].blockingPlay();
Thread.sleep(pause);
In your code, I guess you don't need this.
If you are interested in test a is this, the process would be something like this:
Find number of words in the sound file, requires little knowledge of audio signal processing
Mark their boundaries
Now, half of the work is done. Only remaining part is playing back the sounds of words in reverse order.
Create another Sound, fill the samples array with all segmented pieces of words, but in reverse order. Done.

Related

Counting ones from txt file

I am trying to solve an exercise: I have a txt file with images (20 rows x 20 columns) of 0's and 1's made random. Between each image (20x20) there is a gap of one empty line.
Based on this txt file I have to calculate how many of these images have more 1's than 0's. At the end I need to also find the highest number of 1's occuring in one image.
Here is my code so far ... but I am a little bit lost
import java.io.File;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
File input = new File("path to my txt file");
Scanner scanner = new Scanner(new File("path to my txt file"));
int counter = 0;
while (scanner.hasNext()){
String word1 = scanner.next();
String word2 = scanner.next();
boolean switcher = false;
int howManyOnes ("//path to my image file????") {
int ones = 0;
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 20; j++) {
ones +=?[i][j];
}
}
return ones;
}
}
}
Here is my understanding on which I will base my answer.
Your input is a text file in which each non-blank line has a total of 20 characters some of which are '1' and some of which are '0'.
An "image" is a collection of sequential non-blank lines. When one blank line is present it signals the end of one "image" and the beginning of the next "image".
Your objectives are:
to calculate how many of these images have more 1's than 0's.
and
find the highest number of 1's occurring in one image.
As this appears to be a homework type of question I will give you some guidance regarding how to design your code first and later if you're still struggling I can provide additional details. Please see how to ask and answer homework questions.
Assumptions:
You are allowed to use any of the methods of the String class.
Consider the things you want to track and in what scope you want to keep track of them. You need to be able to identify when an image begins and ends and track how many 1s and 0s you see within that image. That is, when an image begins the number of 1s and number of 0s for that image should be zero and you should increment them as you identify them in each line of the image. Once the image has been processed you will need to reset these to 0 to get ready to process the next image.
At the same time when you're done processing a single image you need to determine if the number of 1s in that image is greater than the number of 1s you've seen in any other image so far and if it is track that value. This value's scope is larger than the values mentioned previously as it is determined by the number of 1s in all of the images. It must NOT be reset with each image. Similarly, the number of images that have more 1s than 0s also has this kind of scope - it should NOT be reset with each image, rather it should be maintained until the entire file has been processed.
Next, consider how you can determine the number of 1s and 0s within an image. It looks like you're thinking about looping through every character and you could do it that way but there is a simpler way and it has to do with the assumption I mentioned.
I hope this gets you started. Please update your question as you write more code and I'll be happy to update my answer as well.

Java - Trying to create an arraylist of strings but the arraylist gets full(?)

I might just be doing something stupid here but I'm trying to write a program that will take all the text from an xml file, put it in an arraylist as strings, then find certain recurring strings and count them. It basically works, but for some reason it won't go through the entire xml file. It's a pretty large file with over 15000 lines (ideally I'd like it to be able to hand any amount of lines though). I did a test to output everything it was putting in the arraylist to a .txt file and eventually the last line simply says "no", and there's still much more text/lines to go through.
This is the code I'm using to make the arraylist (lines is the amount of lines in the file):
// make array of strings
for (int i=0; i<lines; i++) {
strList.add(fin2.next());
}
fin2.close();
Then I'm searching for the desired strings with:
// find strings
for (String string : strList) {
if(string.matches(identifier)){
count++;
}
}
System.out.println(count);
fout.println(count);
It basically works (the printwriter and scanners work, line count works, etc) except the arraylist won't take all the text from the .xml file, so of course the count at the end is inaccurate. Is arraylist not the best solution for this problem?
This is a BAD practice to do. Each time you put a string into an ArrayList and keep it there, you're going to have an increase in memory usage. The bigger the file, the more memory is used up to the point where you're wondering why your application is using 75% of your memory.
You don't need to store the lines into an ArrayList in order to see if they match. You can simply just read the line and compare it to whatever text you're comparing it to.
Here would be your code modified:
String nextString = "";
while (fin2.hasNext()) {
nextString = fin2.next();
if (nextString.matches(identifier) || nextString.matches(identifier2)) {
count++;
}
}
fin2.close();
System.out.pritnln(count);
Eliminates looping through everything twice, saves you a ton of memory, and gives you accurate results. Also I'm not sure if you're meaning to read the entire line, or you have some sort of token. If you want to read the entire line, change hasNext to hasNextLine and next to nextLine
Edit: Modified the code to show what it would look like looking for multiple strings.
Have you tried to use map, like HashMap. Since Your goal is to find the occurrence of word from a xml, hashmap will make your like easier.
The problem is not with your ArrayList but with your for loop. What's happening is that you're using the number of lines in your file as your sentinel value, but rather than incrementing i by 1 every line, you are doing it every word. Therefore, not all the words are added to your ArrayList because your loop terminates earlier than expected. Hope this helps!
EDIT: I don't know what object you are using right now to collect the contents of this xml file, but I would suggest using Scanner instead (passing the File as a parameter in the constructor) and replacing the current for loop with a while loop that uses while (nameOfScanner.hasNextLine())

Java - farkle (greed) game (die and player arrays, multiple classes)

I am trying to write code for a command like game of Farkle (greed). This is an Intro to computer science class. In a nutshell, you roll 6 die, and scores are based off of what you roll. Then you are required to remove the die that were used -> display score from that roll -> display total score -> ask if they would like to roll again. First player to a score determined by the user is the winner.
I have a bunch of code written for the model, and I am working on the view. I am struggling with the view, which makes it harder to advance on my model code. We are required to use the Die and Player classes (we were given those). I use the Die quickly, not quite sure how to apply the Player class.
When I try to run my command line, I am getting out of bounds errors on my rollCheck() array and other issues in my model that were not coming up when I simply was testing in main. I apologize for the amount of code posted, but I figure seeing everything makes it easier to solve (goes without saying really).
If anyone can give me pushes in the right direction to solving and making my program work, that would be great! Thank you.
Without being able to run the program to be sure its hard to be certain (I need the top of GreedGame) but i'd be fairly confident its the following:
in rollDie die is set to an array of ints on size remainingDie
this.die = new int [remainingDie];
later, within rollCheck the contents of the die array up to and including remainingDie, going over the array by 1
for (int i = 0; i <= remainingDie; i++) { // Count up quantity of die (6 set to remaining die)
if (die[i] == 1) {
this.numFreq[0] += 1;
}
....
....
}
So in short I believe i <= remainingDie; should be i < remainingDie; because an array with 6 entries has "boxes" 0,1,2,3,4,5

Splitting up visual blocks of text in java

I have a block of text I'm trying to interpret in java (or with grep/awk/etc) looking like the following:
Somewhat differently, plaques of the rN8 and rN9 mutants and human coronavirus OC43 as well as the more divergent
were of fully wild-type size, indicating that the suppressor mu- SARS-CoV, human coronavirus HKU1, and bat coronaviruses
tations, in isolation, were not noticeably deleterious to the HKU4, HKU5, and HKU9 (Fig. 6B). Thus, not only do mem-
--
able effect on the viral phenotype. A potentially related obser- sented for the existence of an interaction between nsp9
vation is that the mutation A2U, which is also neutral by itself, nsp8 (56). A hexadecameric complex of SARS-CoV nsp8 and
is lethal in combination with the AACAAG insertion (data not nsp7 has been found to bind to double-stranded RNA. The
And what I'd like to do is split it into two parts: left and right. I'm having trouble coming up with a regex or any other method that would split a block of text obviously visually split, but not obvious to a programming language. The lengths of the lines are variable.
I've considered looking for the first block and then finding the second by looking for multiple spaces, but I'm not sure that that's a robust solution. Any ideas, snippets, pseudo code, links, etc?
Text Source
The text has been ran as follows through pdftotext pdftotext -layout MyPdf.pdf
Blur the text and come up with an array of the character density per column of text. Then look for gaps and split there.
String blurredText = text.replaceAll("(?<=\\S) (?=\\S)", ".");
String[] blurredLines = text.split("\r\n?|\n");
int maxRowLength = 0;
for (String blurredLine : blurredLines) {
maxRowLength = Math.max(maxRowLength, blurredLine.length());
}
int[] columnCounts = new int[maxRowLength];
for (String blurredLine : blurredLines) {
for (int i = 0, n = blurredLine.length(); i < n; ++i) {
if (blurredLine.charAt(i) != ' ') { ++columnCounts[i]; }
}
}
// Look for runs of zero of at least length 3.
// Alternatively, you might look for the n longest runs of zeros.
// Alternatively, you might look for runs of length min(columnCounts) to ignore
// horizontal rules.
int minBreakLen = 3; // A tuning parameter.
List<Integer> breaks = new ArrayList<Integer>();
outer: for (int i = 0; i < maxRowLength - minBreakLen; ++i) {
if (columnCounts[i] != 0) { continue; }
int runLength = 1;
while (i + runLength < maxRowLength && 0 == columnCounts[i + runLength]) {
++runLength;
}
if (runLength >= minBreakLen) {
breaks.add(i);
}
i += runLength - 1;
}
System.out.println(breaks);
I doubt there is any robust solution to this. I would go for some sort of heuristic approach.
Off the top of my head, I would calculate a histogram of the column index of the first character of each word, and split on the column with the highest score (the idea being to find lots of words that are all aligned horizontally). I might also choose to weight this based on the number of preceding spaces.
I work in this general area. I am surprised that a double-column bioscience text of recent times (SARS, etc.) would be rendered in double-column monospace as the original - it would be typeset in proportional font or in HTML. So I suspect your text came from some other format (such as PDF). If so then you should try to get that format. PDF is horrible to parse, but PDF flattened to monospace is probably worse.
If you possibly can find someone who has worked in the area and see what they have done. If you have multiple documents (e.g. from different journals or reports) then your problem is worse. Yes, I could write an algorithm to solve the example you have posted, but my guess is it will break on the next set of documents. You will end up customising this for each different source (I and others have had to do this).
UPDATE: Thanks. As it's PDF then I would start by asking around. We collaborate with the group at Penn State (who have also done Citeseer). I also have colleagues at Cambridge who have spent months on a PDF reader.
If you want to do it yourself - and it will take time - then I'd start with PDFBox. I've done quite a lot with this and I think it's better for this than pdf2text or pdftotext. I can't remember whether it has double column option - I think so
UPDATE Here is a recent answer of several ways of tackling double-column PDF
http://metaoptimize.com/qa/questions/3943/methods-for-extracting-two-column-text-from-a-pdf
I'd certainly see what other people have done.
FWIW I spend a lot of time trying to convince people that scientists should not create their output in PDF because it destroys machine parsing - as you and I have found
UPDATE. You get the PDFs from your PI (== Principal Investigator?) In which case you'll gets lots of different sources which makes it worse.
What is the real problem you are trying to solve? I may be able to help

Printing an ArrayList of Strings to a PrintWriter with word wrap

Some classmates and I are working on a homework assignment for Java that requires we print an ArrayList of Strings to a PrintWriter using word wrap, so that none of the output passes 80 characters. We've extensively Googled this and can't find any Java API based way to do this.
I know it's generally "wrong" to ask a homework question on SO, but we're just looking for recommendations of the best way to do this, or if we missed something in the API. This isn't the major part of the homework, just a small output requirement.
Ideally, I'd like to be able to wordwrap the ArrayList's toString since it's nicely formatted already.
Well, this is a first for me, it's the first time one of my students has posted a question about one of the projects I've assigned them. The way it was phrased, that he was looking for an algorithm, and the answers you've all shared are just fine with me. However, this is a typical case of trying to make things too complicated. A part of the spec that was not mentioned was that the 80 characters limit was not a hard limit. I said that each line of the output file had to be roughly 80 characters long. It was OK to go over 80 a little. In my version of the solution, I just had a running count and did a modulus of the count to add the line end. I varied the value of the modulus until the output file looked right. This resulted in lines with small numbers being really short so I used a different modulus when the numbers were small. This wasn't a big part of the project and it's interesting that this got so much attention.
Our solution was to create a temporary string and append elements one by one, followed by a comma. Before adding an element, check if adding it will make the string longer than 80 characters and choose whether to print it and reset or just append.
This still has the issue with the extra trailing comma, but that's been dealt with so many times we'll be fine. I was looking to avoid this because it was originally more complicated in my head than it really is.
I think that better solution is to create your own WrapTextWriter that wraps any other writer and overrides method public void write(String str, int off, int len) throws IOException. Here it should run in loop and perform logic of wrapping.
This logic is not as simple as str.substring(80). If you are dealing with real text and wish to wrap it correctly (i.e. do not cut words, do not move comas or dots to the next line etc) you have to implement some logic. it is probably not too complicated but probably language dependent. For example in English there is not space between word and colon while in French they put space between them.
So, I performed 5 second googling and found the following discussion that can help you.
private static final int MAX_CHARACTERS = 80;
public static void main(String[] args)
throws FileNotFoundException
{
List<String> strings = new ArrayList<String>();
int size = 0;
PrintWriter writer = new PrintWriter(System.out, true); // Just as example
for (String str : strings)
{
size += str.length();
if (size > MAX_CHARACTERS)
{
writer.print(System.getProperty("line.separator") + str);
size = 0;
}
else
writer.print(str);
}
}
You can simply write a function, like "void printWordWrap(List<String> strings)", with that algorithm inside. I think, it`s a good way to solve your problem. :)

Categories

Resources