Sound free response answer 6

The Sound problem from the 2011 AP Computer Science Exam is typical of free response problems that test arrays. The problem requires you to find and modify elements that exceed a given limit.

Review the Sound free response problem with AP CS Tutor Brandon Horn.

Sound Part (a): limitAmplitude

 public int limitAmplitude(int limit)
 {
  int numChanges = 0;

  for (int i = 0; i < samples.length; i++)
  {
   if (samples[i] > limit)
   {
    samples[i] = limit;
    numChanges++;
   }
   else if (samples[i] < -limit)
   {
    samples[i] = -limit;
    numChanges++;
   }
  }

  return numChanges;
 }

Sound Part (b): trimSilenceFromBeginning

public void trimSilenceFromBeginning()
{
  int leadingZeros = 0;

  // precondition guarantees at least 1 non-zero element
  // so no need to check for out of bounds
  while(samples[leadingZeros] == 0)
   leadingZeros++;
  
  int[] withoutLeadingZeros = new int[samples.length - leadingZeros];

  for(int i = leadingZeros; i < samples.length; i++)
    withoutLeadingZeros[i - leadingZeros] = samples[i];

  samples = withoutLeadingZeros;
}

Get AP CS Help

2011 AP CS Exam Free Response Solutions

Recommended Practice Problems

6 thoughts on “Sound free response answer

  1. Reply Mr. Zurla May 6,2011 11:09 am

    it appears that your array “withoutzeros” will have length 8 for the example array “samples” as given in question 1b when it should have length 12. might want to rework your loops

    • Reply Brandon Horn May 6,2011 12:31 pm

      I should have followed my own advice and read the problem carefully. My original solution removed all zeros in the array, not just leading zeros. I’ve updated the post to reflect a correct solution. Thanks for the report.

  2. Reply Taylor Apr 24,2013 9:25 pm

    This seems like an easier solution

    int count = 0;
    int leadingZeros= 0;
    int loopControlVar = 0;
    boolean silence = 0;
    int [] newSamples = new int[loopControlVar - leadingZeros];
    for(int temp : samples)
    {
      if(temp==0 && silence == true)
      {
        loopControlVar++;
        leadingZeros++;
      }
      else 
      {
        silence = false;
        newSamples[count] = temp;
        count++;
      }
    }
    
    • Reply Brandon Horn Apr 24,2013 9:37 pm

      Your proposed solution incorrectly declares the length of newSamples to be 0. Modifying the values of loopControlVar and leadingZeros within the loop does not retroactively alter the length of the array.

      It is necessary to determine the number of leading zeros before initializing the new array. This requires 2 traversals of the array (one traversal is partial).

      • Reply Taylor Apr 24,2013 10:20 pm

        I see what you mean.

        This would work right?

        int count = 0;
        int leadingZeros = 0;
        boolean silence = true;
                
        for(int temp : samples)
        { 
          if (temp == 0 && silence == true)
          {
            leadingZeros++;
          }
          else 
          {
            silence = false;
          }
        }
               
        int [] newSamples = int [samples.length - leadingZeros];
        silence = true;
               
        for(int temp : samples)
        {
          if(temp == 0 && silence == true)
          {
            
          }
          else 
          {
            silence = false;
            newSamples[count] = temp;
            count++;
          }
        }
        

        Dang. That is really is much more complicated than your solution though.

        Thank you

        • Reply Brandon Horn Apr 25,2013 7:48 am

          Is the goal of this solution to replace the call to arraycopy with a second loop? A regular for loop would work better than a foreach loop since you need the index.

          for(int i = 0; i < newSamples.length; i++)
            newSamples[i] = samples[leadingZeros + i];
          

          Your approach to tracking silence using the variable silence isn't wrong but it is unnecessary. The first loop in my solution tracks silence without the extra variable. Your use of silence in your second loop is also unnecessary. leadingZeros is sufficient to identify the offset of the first non-zero value from the beginning of the array.

          Other comments on your code:

          • silence == true is a silly comparison. silence is already a boolean.
          • temp is a poor name for your loop variable because it doesn't identify its purpose. value would be better since it suggests a value in the array.
          • The if statement in your second loop is blank and has an else statement. Check the opposite instead.

Leave a Reply