Еще одна вариация (работает ли она с IE?):
String.prototype.reverse = function() {
for (i=1,s=""; i<=this.length; s+=this.substr(-i++,1)) {}
return s;
}
EDIT:
Это без использования встроенных функций:
String.prototype.reverse = function() {
for (i=this[-1],s=""; i>=0; s+=this[i--]) {}
return s;
}
Примечание: этот [-1] содержит длину строки.
Однако невозможно изменить строку на месте, поскольку присвоение отдельным элементам массива не работает с объектом String (защищенный?). То есть вы можете назначать, но результирующая строка не изменяется.
Невозможно напрямую читать / записывать отдельные биты, наименьший блок, который вы можете читать / записывать, - это байт.
Вы можете использовать стандартные побитовые операторы для управления байт, так, например, для получения младших 2 бит байта вы бы
byte b = in.readByte();
byte lowBits = b&0x3;
устанавливали низкие 4 бита в 1 и записывали байт:
b |= 0xf;
out.writeByte(b);
(Примечание, ради эффективности вы можете читать / писать байтовые массивы, а не одиночные байты)
Да и нет. На большинстве современных компьютеров байт является наименьшей адресной единицей памяти, поэтому вы можете читать и записывать только все байты за раз. Тем не менее, вы всегда можете использовать побитовые операторы для управления битами внутри байта.
Нижеприведенный код должен работать
int[] mynumbers = {3,4};
BitSet compressedNumbers = new BitSet(mynumbers.length*3);
// let's say you encoded 3 as 101 and 4 as 010
String myNumbersAsBinaryString = "101010";
for (int i = 0; i < myNumbersAsBinaryString.length(); i++) {
if(myNumbersAsBinaryString.charAt(i) == '1')
compressedNumbers.set(i);
}
String path = Resources.getResource("myfile.out").getPath();
ObjectOutputStream outputStream = null;
try {
outputStream = new ObjectOutputStream(new FileOutputStream(path));
outputStream.writeObject(compressedNumbers);
} catch (IOException e) {
e.printStackTrace();
}
Afaik не существует функции для этого в Java API. Однако вы можете, конечно, прочитать байт, а затем использовать функции манипуляции бит. То же самое касается написания.
Переместился на https://github.com/jinahya/bit-io
. Посмотрите на http://jinahya.googlecode.com/ svn / trunk / com.googlecode.jinahya / bit-io / src / main / java / com / googlecode / jinahya / io /
<dependency>
<!-- resides in central repo -->
<groupId>com.googlecode.jinahya</groupId>
<artifactId>bit-io</artifactId>
<version>1.0-alpha-13</version>
</dependency>
Это небольшая удобная библиотека для чтения / запись произвольной длины бит с помощью Java.
final InputStream stream;
final BitInput input = new BitInput(new BitInput.StreamInput(stream));
final int b = input.readBoolean(); // reads a 1-bit boolean value
final int i = input.readUnsignedInt(3); // reads a 3-bit unsigned int
final long l = input.readLong(47); // reads a 47-bit signed long
input.align(1); // 8-bit byte align; padding
final WritableByteChannel channel;
final BitOutput output = new BitOutput(new BitOutput.ChannelOutput(channel));
output.writeBoolean(true); // writes a 1-bit boolean value
output.writeInt(17, 0x00); // writes a 17-bit signed int
output.writeUnsignedLong(54, 0x00L); // writes a 54-bit unsigned long
output.align(4); // 32-bit byte align; discarding
InputStreams и OutputStreams - потоки байтов.
Чтобы прочитать бит, вам нужно будет прочитать байт, а затем использовать манипуляции с битами, чтобы проверить интересующие вас биты. Аналогично, для записи битов вам нужно написать байты, содержащие нужные вам биты.
Невозможно сделать это напрямую. Меньшие единицы компьютеров могут обрабатывать байты (даже булевы занимают байты). Однако вы можете создать собственный класс потока, который упаковывает байт с нужными битами, а затем записывает его. Затем вы можете создать оболочку для этого класса, у которого функция записи принимает некоторый интегральный тип, проверяет, что она находится между 0 и 7 (или -4 и 3 ... или что-то еще), извлекает биты так же, как и класс BitInputStream (ниже) делает и выполняет соответствующие вызовы метода записи BitOutputStream. Возможно, вы думаете, что можете просто создать один набор классов потока ввода-вывода, но 3 не равномерно распределяется по 8. Поэтому, если вам нужна оптимальная эффективность хранения, и вы не хотите работать очень сильно, вы застряли с двумя уровнями абстракции. Ниже приведен класс BitOutputStream, соответствующий класс BitInputStream и программа, которая гарантирует их работу.
import java.io.IOException;
import java.io.OutputStream;
class BitOutputStream {
private OutputStream out;
private boolean[] buffer = new boolean[8];
private int count = 0;
public BitOutputStream(OutputStream out) {
this.out = out;
}
public void write(boolean x) throws IOException {
this.count++;
this.buffer[8-this.count] = x;
if (this.count == 8){
int num = 0;
for (int index = 0; index < 8; index++){
num = 2*num + (this.buffer[index] ? 1 : 0);
}
this.out.write(num - 128);
this.count = 0;
}
}
public void close() throws IOException {
int num = 0;
for (int index = 0; index < 8; index++){
num = 2*num + (this.buffer[index] ? 1 : 0);
}
this.out.write(num - 128);
this.out.close();
}
}
Я уверен, что есть способ упаковать int с битовыми операторами и, таким образом, избежать для изменения ввода, но я не думаю, что это трудно.
Кроме того, вы, вероятно, заметили, что нет локального способа обнаружить, что последний бит был прочитан в этой реализации, но я really не хотят думать , что hard.
import java.io.IOException;
import java.io.InputStream;
class BitInputStream {
private InputStream in;
private int num = 0;
private int count = 8;
public BitInputStream(InputStream in) {
this.in = in;
}
public boolean read() throws IOException {
if (this.count == 8){
this.num = this.in.read() + 128;
this.count = 0;
}
boolean x = (num%2 == 1);
num /= 2;
this.count++;
return x;
}
public void close() throws IOException {
this.in.close();
}
}
Возможно, вы это знаете, но вы должны поместить BufferedStream между вашим BitStream и FileStream или это займет много времени.
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Random;
class Test {
private static final int n = 1000000;
public static void main(String[] args) throws IOException {
Random random = new Random();
//Generate array
long startTime = System.nanoTime();
boolean[] outputArray = new boolean[n];
for (int index = 0; index < n; index++){
outputArray[index] = random.nextBoolean();
}
System.out.println("Array generated in " + (double)(System.nanoTime() - startTime)/1000/1000/1000 + " seconds.");
//Write to file
startTime = System.nanoTime();
BitOutputStream fout = new BitOutputStream(new BufferedOutputStream(new FileOutputStream("booleans.bin")));
for (int index = 0; index < n; index++){
fout.write(outputArray[index]);
}
fout.close();
System.out.println("Array written to file in " + (double)(System.nanoTime() - startTime)/1000/1000/1000 + " seconds.");
//Read from file
startTime = System.nanoTime();
BitInputStream fin = new BitInputStream(new BufferedInputStream(new FileInputStream("booleans.bin")));
boolean[] inputArray = new boolean[n];
for (int index = 0; index < n; index++){
inputArray[index] = fin.read();
}
fin.close();
System.out.println("Array read from file in " + (double)(System.nanoTime() - startTime)/1000/1000/1000 + " seconds.");
//Delete file
new File("booleans.bin").delete();
//Check equality
boolean equal = true;
for (int index = 0; index < n; index++){
if (outputArray[index] != inputArray[index]){
equal = false;
break;
}
}
System.out.println("Input " + (equal ? "equals " : "doesn't equal ") + "output.");
}
}
Если вы просто записываете биты в файл, класс BitSet класса Java может стоить взглянуть. Из javadoc:
Этот класс реализует вектор бит, который растет по мере необходимости. Каждый компонент битового набора имеет логическое значение. Биты BitSet индексируются неотрицательными целыми числами. Отдельные индексированные биты могут быть проверены, установлены или очищены. Один BitSet может использоваться для изменения содержимого другого BitSet с помощью логических логических И, логических включений OR и логических исключающих операций OR.
Вы можете преобразовать BitSets в long [] и byte [ ] для сохранения данных в файл.
Биты упакованы в байтах, и кроме VHDL / Verilog я не видел языка, который позволяет добавлять отдельные биты в поток. Загрузите свои биты и упакуйте их в байты для записи с использованием буфера и битмаскинга . Сделайте обратное для чтения, т. Е. Держите указатель в своем буфере и увеличивайте его, когда вы возвращаете индивидуально маскированные биты.