Java tutorial
/* * @(#)PalindromeArray.java 1.0 Apr 26, 2008 * * The MIT License * * Copyright (c) 2008 Malachi de AElfweald <malachid@gmail.com> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ //package org.eoti.math; import java.math.BigInteger; import java.util.Iterator; import java.util.concurrent.ConcurrentHashMap; public class PalidromeArray implements Iterable<BigInteger> { protected static final BigInteger TWO = BigInteger.valueOf(2); protected ConcurrentHashMap<BigInteger, BigInteger> array; protected BigInteger totalLength, halfLength; protected boolean isEven = true; public static PalidromeArray fromString(String s) { String[] arr = s.split("\\|"); BigInteger[] bi = new BigInteger[arr.length]; for (int i = 0; i < arr.length; i++) bi[i] = new BigInteger(arr[i]); return new PalidromeArray(bi); } public PalidromeArray(PalidromeArray array) { this.totalLength = array.totalLength; this.halfLength = array.halfLength; this.isEven = array.isEven; this.array = new ConcurrentHashMap<BigInteger, BigInteger>(); for (BigInteger index : array.array.keySet()) this.array.put(index, array.array.get(index)); } public PalidromeArray(BigInteger[] array) { this.totalLength = BigInteger.valueOf(array.length); this.halfLength = totalLength.divide(TWO); if (MathUtil.isOdd(totalLength)) { isEven = false; halfLength = halfLength.add(BigInteger.ONE); } this.array = new ConcurrentHashMap<BigInteger, BigInteger>(); BigInteger index = BigInteger.ZERO; for (BigInteger bi : array) { this.array.put(index, bi); index = index.add(BigInteger.ONE); } } public PalidromeArray(BigInteger totalLength) { this.totalLength = totalLength; this.halfLength = totalLength.divide(TWO); if (MathUtil.isOdd(totalLength)) { isEven = false; halfLength = halfLength.add(BigInteger.ONE); } array = new ConcurrentHashMap<BigInteger, BigInteger>(); } public String toString() { StringBuilder sb = new StringBuilder(); boolean first = true; for (BigInteger bi : this) { if (!first) sb.append("|"); sb.append(bi); first = false; } return sb.toString(); } public BigInteger halfLength() { return halfLength; } public BigInteger totalLength() { return totalLength; } public BigInteger get(BigInteger position) { /** * {1,4,6,4,1} would have {1,4,6} in our array * 0: return 1 * 1: return 4 * 2: return 6 * 3: return 4 * 4: return 1 * totalLength = 5 * halfLength = 3 * get(0) returns #0 * get(1) returns #1 * get(2) returns #2 * get(3) returns #1 * get(4) returns #0 * * {1,3,3,1} would have {1,3} in our array * array.length = 2 * 0: return 1 * 1: return 3 * 2: return 3 * 3: return 1 * totalLength = 4 * halfLength = 2 * get(0) returns #0 * get(1) returns #1 * get(2) returns #1 * get(3) returns #0 */ if (position.subtract(halfLength).signum() < 0) return array.get(position); BigInteger mid = halfLength.subtract(BigInteger.ONE); if (isEven) return array.get(mid.subtract(position.subtract(halfLength))); return array.get(mid.subtract(position.subtract(mid))); } public void set(BigInteger position, BigInteger value) { array.put(position, value); } public Iterator<BigInteger> iterator() { return new PalidromeArrayIterator(this); } class PalidromeArrayIterator implements Iterator<BigInteger> { protected PalidromeArray array; protected BigInteger position = BigInteger.ZERO; public PalidromeArrayIterator(PalidromeArray array) { this.array = array; } public boolean hasNext() { return array.totalLength.subtract(position).signum() > 0; } public BigInteger next() { BigInteger index = position; position = position.add(BigInteger.ONE); return array.get(index); } public void remove() { throw new UnsupportedOperationException("Not supported"); } } }