Kaal
Kaal

Reputation: 111

Java Get the position of a value using an arraylist

I'm trying to get the position of the STX (0x02) from the byte array message below. If you see the message, it has 0x2 in a number of places but the only position I want is the STX one. I've been looping through it backwards using a for loop. I have to loop backwards btw. I've tried a number of ways but I'm having difficulty getting that position. One way I've tried but has not worked is, wherever a 0x2 is, and has elements of 3 or more between that and an ETX (0x3) in front of it get that position of that STX. But I'm doing something wrong because I keep on getting an error which I am having difficulty resolving. Can you please help?

EDIT: If there is a better way then my logic of finding that position (STX) by distinguishing it from the other 0x2, please can you provide that.

EDIT: I have to loop backwards as that is required by the instructions given to me.

EDIT: Here is the code:

    //Test 3:
    public String Test3(List<Byte> byteList) {
        //checking positions of the STX and ETX
        //looping through the array backwards
        for (int i = byteList.size() - 1; i >= 0; i--) {                
            if (byteList.get(i) == STX && (i >= 3 && byteList.get(i) == ETX)) {
                STXpos = i;
            }
        }       
        return STXpos;
    }
    byte[] validMsgWithRandomData = {0x32,0x32,0x32, //Random data
    0x02, // STX
    0x31,0x32,0x10,0x02,0x33, // Data 31 32 02 33
    0x03, // ETX
    0x31^0x32^0x02^0x33^0x03,// LRC calculated from the data (with the DLE removed) plus the ETX
    0x2,0x3,0x00,0x02 //Random data
};

Upvotes: 0

Views: 491

Answers (2)

SR_
SR_

Reputation: 917

My first attempt with backward loop and in O(n) complexity.

EDIT : getting rid of candidate for STX.

EDIT 2 : This solution works at least for a few cases including OP's one (but it has not been tested extensively...).

    final int NOTFOUND = -1;
    final int ETX = 0x03;
    final int STX = 0x02;
    int stxpos = NOTFOUND;
    int etxpos = NOTFOUND;
    int etxcandidatepos = NOTFOUND;
    for (int i = validMsgWithRandomData.length - 1; i >=0; --i)
    {
        if (ETX == validMsgWithRandomData[i])
        {
            etxcandidatepos = i;
            if (NOTFOUND == etxpos)
            {
                etxpos = i;
                stxpos = NOTFOUND;
            }
        }
        else if (STX == validMsgWithRandomData[i])
        {
            if (NOTFOUND != etxpos)
            {
                stxpos = i;
                if (NOTFOUND != etxcandidatepos)
                {
                    etxpos = etxcandidatepos;
                    etxcandidatepos = NOTFOUND;
                }
            }
        }
    }

Upvotes: 2

Zilicon
Zilicon

Reputation: 3860

Since the amount of elements between STX and ETX is not a constant, i'd search in normal order and look for ETX after I find STX:

public String Test3(List<Byte> byteList) {
    // find potential STX
    for (int i = 0; i < byteList.size(); ++i) {
        if (byteList.get(i) == STX) {
            // make sure matching ETX exists
            for (int j = i + 1; j < byteList.size(); ++j) {
                if (byteList.get(j) == ETX) {
                    return i;
                }
            }
        }
    }
}

You can also do it in reverse order if you really want:

public String Test3(List<Byte> byteList) {
    // find potential ETX
    for (int i = byteList.size() - 1; i > 0; --i) {
        if (byteList.get(i) == ETX) {
            // make sure matching STX exists
            for (int j = i - 1; j > 0; --j) {
                if (byteList.get(j) == STX) {
                    return j;
                }
            }
        }
    }
}

By the way if you want to force a distance of elements between STX and ETX you can do it by changing j's initialization.

Upvotes: 1

Related Questions