1

I'm creating a method which finds smallest absolute difference between next and previous elements value.

It occurs that ArgumentOutofRange exception in method. But however when i add try, catch exception it works. What was the problem in my code? however i created proper conditions like "if i equals 0" of course it can't find [i-1], then its will be difference between next value[1] and [0]. And if its became last element then value will be difference between its(last[i-1]) and previous ([i-2])

namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Cla> Clalist = new List<Cla>();
            Clalist.Add(new Cla(0));
            Clalist.Add(new Cla(2));
            Clalist.Add(new Cla(3));
            Clalist.Add(new Cla(10));
            Clalist.Add(new Cla(100));
            Clalist.Add(new Cla(65));

            Program nn = new Program();
            nn.GetAbs(Clalist);

            Console.WriteLine(Clalist[0].AbsValue);
            Console.WriteLine(Clalist[1].AbsValue);
            Console.WriteLine(Clalist[2].AbsValue);
            Console.WriteLine(Clalist[3].AbsValue);
            Console.WriteLine(Clalist[4].AbsValue);
            Console.WriteLine(Clalist[5].AbsValue);

            Console.ReadLine();
        }
        public void GetAbs(List<Cla> n)
        {
            int z = n.Count;
            for (int i = 0; i < z; i++)
            {
                if(i == 0)
                {
                    n[0].AbsValue = Math.Abs(n[1].Value - n[0].Value);
                }
                if(i == (z-1))
                {
                    n[z-1].AbsValue = Math.Abs(n[z-1].Value - n[z -2].Value);
                }
                else
                {
                    try
                    {
                        var AbsV = Math.Abs(n[i + 1].Value - n[i].Value);
                        var AbsV2 = Math.Abs(n[i - 1].Value - n[i].Value); //exception occurs here
                        if (AbsV < AbsV2)
                            n[i].AbsValue = AbsV;
                        else
                            n[i].AbsValue = AbsV2;
                    }
                 /*   catch (ArgumentOutOfRangeException)
                    {
                        n[0].AbsValue = n[1].Value - n[0].Value; */ When i add this it works
                    }
                    }
                }
            }
        }
    }

    class Cla
    {
        public int Value;
        public int AbsValue;
        public Cla(int v)
        {
            Value = v;
        }
    }
Julian
  • 33,915
  • 22
  • 119
  • 174
ldn
  • 147
  • 1
  • 9
  • 4
    change `if(i == (z-1))` into `else if(i == (z-1))` – Dmitry Bychenko Apr 18 '17 at 19:23
  • 2
    Possible duplicate of [What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?](http://stackoverflow.com/questions/5554734/what-causes-a-java-lang-arrayindexoutofboundsexception-and-how-do-i-prevent-it) - different language, same issue – John Dvorak Apr 18 '17 at 19:27
  • @DmitryBychenko спасибо Димитри, она работает – ldn Apr 18 '17 at 19:28
  • @Dagvanorov Lkhagvajav: you are welcome! (Пожалуйста!) – Dmitry Bychenko Apr 18 '17 at 19:29
  • @JanDvorak, if the answers on that question can *directly* be applied to C#, then the tag should be added to the question, particularly if you expect to close C# questions with it as a duplicate-target. Doing so will also help people find the question, if it is applicable to multiple languages. – Makyen Apr 18 '17 at 19:38
  • @Makyen you can't add all of the language tags to a single question as the tag limit is five. You could suggest removing the java tag instead, though. – John Dvorak Apr 18 '17 at 19:39
  • Another option would be to go for the "unlikely to help others" (AKA typo) close reason, less useful for the asker. – John Dvorak Apr 18 '17 at 19:40
  • @JanDvorak, FYI: That specific close reason was recently brought up on meta in [Should we close vote all questions that are resolved in a manner unlikely to help future readers?](https://meta.stackoverflow.com/q/348025/3773011). – Makyen Apr 18 '17 at 21:02

2 Answers2

4

You should have three mutually exclusive cases:

  1. i == 0 (left border)
  2. i == z - 1 (right border)
  3. i == 1..z-2 (inner values)

like this:

for (int i = 0; i < z; i++)
{
    if (i == 0)           // 1st case (left border)
    {
        n[0].AbsValue = Math.Abs(n[1].Value - n[0].Value);
    }
    else if(i == (z-1))  // 2nd (please, notice "else if") (right border)
    {
       n[z-1].AbsValue = Math.Abs(n[z-1].Value - n[z -2].Value);
    }
    else // 3d (inner values)
    {
    ....
    }
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
1

The line that throws the exception occurs when i == 0. Either the second if statement needs to become an else if, or the else needs to become an else if(i > 0).

Julian
  • 33,915
  • 22
  • 119
  • 174
Peter Beacom
  • 41
  • 1
  • 9