如何用按位操作替换此String操作?

时间:2019-01-29 20:00:34

标签: java string algorithm kotlin bitwise-operators

考虑到我在Base对象中具有以下字段:

//these fields have their bits constantly permuted
//and have their values defined to "011233455677..."
//to integers acts like Strings

var ul = 0x011233
var ur = 0x455677
var dl = 0x998bba
var dr = 0xddcffe

考虑到我有这种方法可以将这些字段作为字符串值操作

private fun Cubo.isSolved(): Boolean {             
    val solved = Base()

    //function to append "leading zero" to the hex integer
    fun fill(s: String) = if (s.length == 5) "0$s" else s

    //all these fields are declared at the global escope

    //converted ul, ur, dl, dr from solved obj to hex string
    a1 = fill(Integer.toHexString(solved.ul))
    b1 = fill(Integer.toHexString(solved.ur))
    c1 = fill(Integer.toHexString(solved.dl))
    d1 = fill(Integer.toHexString(solved.dr))

    //concats the converteds ul and ur into a new one
    ab1 = a1 + b1
    //concats the converteds dl and dr into a new one
    cd1 = c1 + d1

    //do the same with fields of THIS object
    a2 = fill(Integer.toHexString(this.ul))
    b2 = fill(Integer.toHexString(this.ur))
    c2 = fill(Integer.toHexString(this.dl))
    d2 = fill(Integer.toHexString(this.dr))
    ab2 = a2 + b2
    cd2 = c2 + d2

    //checks if concatenated fields from THIS object exists inside the 
    //duplicated [solved] object fields.
    //This will help me to check if fields from THIS object are 
    //cyclic/circular permutations of the [solved] object.
    return (ab1 + ab1).contains(ab2) && (cd1 + cd1).contains(cd2)
}

我的目标是一旦字段为整数,就知道如何用按位运算替换该运算?

我之所以这样做,是因为我的应用程序运行缓慢,并且一旦被循环调用数千次,该方法就会降低其性能,然后意识到可以通过使用bitwising操作来提高应用程序性能。

为简化此方法的思想,它仅用于验证字段THIS对象是否对应于“ SOLVED”对象的字段,但这是考虑到测试对象的字段为循环排列。

2 个答案:

答案 0 :(得分:0)

串联

“连接”两个十六进制的6位数字实际上是第一个数字的左移24位(因为每个十六进制数字都有4位且长度为6),第二个数字按位or转变的结果。

infix fun Long.hexConcat(num: Long) = num.or(shl(24))

包含

要检查12位十六进制数字的前6位或后6位中是否包含6位十六进制数字,可以按位and将它们都按位and(以测试结尾)。要测试它是否一开始就必须先将它右移24位,然后按位infix fun Long.containsAsHex(num: Long) = and(num) == num || shr(24) == num

fun main() {

    val a = 0x011233L
    val b = 0x455677L

    val c = a hexConcat b

    println(c.toString(16)) // 11233455677
    println(c containsAsHex a) // true
}

示例:

hexConcat

当然,您可以进一步设置and的参数,以不将其限制为6位十六进制数字。


如果6位数的十六进制数字可以在12位数的十六进制数字中的任意位置:

要检查十六进制数字是否“包含”另一个数字,请将其右移4位直到其值为0,或者找到匹配项,这意味着按数字infix fun Long.containsAsHex(num: Long): Boolean { var shifted = this while (true) { if(shifted.and(num) == num) { return true } if(shifted == 0L) { return false } shifted = shifted.shr(4) // shift one hex digit } @Suppress("UNREACHABLE_CODE") return false } 按数字进行移位的被测数字具有等于要测试的数字。

int *twoSum(int *nums, int numsSize, int target)
{

    for (int i = 0; i < nums.length; i++)
    {
        for (int j = i + 1; j < nums.length; j++)
        {
            int arrayR[2];

            if (nums[j] == target - nums[i])
            {
                return arrayR[]{i, j};
            }
        }
    }
}

int main()
{

    int array[5] = {1, 2, 3, 4, 5};
    int *results[2];
    results = twoSum(array, 5, 3);

    return 0;
}

答案 1 :(得分:0)

假设您的目标状态是固定的,并且固定大小为12个十六进制字符,那么我会做一些不同的事情。我首先要预先计算solved的所有旋转,然后使用简单的等式对它们进行检查。我不确定将其存储在您的应用程序中有意义。在这段代码中,我将其作为target参数传递。

class Cubo() {

    var ul: Int = 0x011233
    var ur: Int = 0x455677
    var dl: Int = 0x998bba
    var dr: Int = 0xddcffe

    constructor(ul: Int, ur: Int, dl: Int, dr: Int) : this() {
        this.ul = ul
        this.ur = ur
        this.dl = dl
        this.dr = dr
    }

    fun isSolved(target: TargetState): Boolean {
        return target.checkSolved(this)
    }
}


class TargetState(val uRot: AllRotations, val dRot: AllRotations) {
    constructor(c: Cubo) : this(AllRotations(concat(c.ul, c.ur)), AllRotations(concat(c.dl, c.dr))) {
    }

    fun checkSolved(c: Cubo): Boolean {
        val u = concat(c.ul, c.ur)
        val d = concat(c.dl, c.dr)
        return uRot.contains(u) and dRot.contains(d)
    }

    companion object {
        fun concat(l: Int, r: Int): Long {
            return l.toLong().shl(AllRotations.singleBitsCount).or(r.toLong())
        }

    }
}


class AllRotations(value: Long) {

    val rotatedValues = Array<Long>(doubleDigitsCount) { i -> rotate(value, digitSize * i) }

    fun contains(test: Long): Boolean {
        for (v in rotatedValues) {
            if (v == test)
                return true
        }
        return false
    }


    companion object {
        const val singleDigitsCount = 6
        const val doubleDigitsCount = 2 * singleDigitsCount
        const val digitSize = 4
        const val singleBitsCount = digitSize * singleDigitsCount
        const val doubleBitsCount = digitSize * doubleDigitsCount
        const val mask = 1L.shl(doubleBitsCount) - 1


        fun rotate(value: Long, shift: Int): Long {
            val hi = value.shl(shift).and(mask)
            val lo = value.shr(doubleBitsCount - shift)
            return hi.or(lo)
        }
    }
}

这是一个有效的简单测试:

val solved = Cubo(0x011233, 0x455677, 0, 0)
val targetState = TargetState(solved)

val c1 = Cubo(0x233455, 0x677011, 0, 0)
val c2 = Cubo(0x455677, 0x011233, 0, 0)
val cbad = Cubo(0x455677, 0x011233, 1, 0)

println(c1.isSolved(targetState))
println(c2.isSolved(targetState))
println(cbad.isSolved(targetState))