Это должно сработать, если вы хотите сохранить первое вхождение каждого нецифрового слова. Вы всегда можете обмануть условие, чтобы оно имело максимум две цифры.
def cleanup(s):
words = set()
for (word, nextword) in zip(s.split(), s.split()[1:] + [None]):
if word.isdigit():
yield word
continue
if not word in words:
words.add(word)
yield word
elif nextword and nextword.isdigit():
yield word
print ' '.join(cleanup("East Zone Mbc26 East Zone 1 2nd S11B Smds Smoke Damper 1 Status"))
print ' '.join(cleanup("GF Command Room 1 Unit 1 Flow Temperature Temperature"))
Выход
East Zone Mbc26 Zone 1 2nd S11B Smds Smoke Damper 1 Status
GF Command Room 1 Unit 1 Flow Temperature
Необходимо смотреть на Буферы Протокола от Google, который поддерживает и C++ и Java.
Именованные каналы были бы более эффективными, чем TCP, но как насчет того, чтобы просто использовать блоки общей памяти?
Я не знаю, какие примитивы существуют на стороне Java для взаимодействия через интерфейс с общей памятью, но со стороны C++ было бы более эффективно получить доступ к данным в общей памяти, чем чтение это или из сокета или из именованного канала. Необходимо было бы реализовать собственное управление потоком и блокирующиеся примитивы, но они могли быть довольно прямыми.
Я использовал бы локальный сокет, который является, как Вы заявляете, самый межплатформенный метод.
Копии пространства пользователя ядра не должны быть проблемой начиная ни с какого другого метода, который Вы могли выбрать, будет requiere этот вид копии за исключением, возможно, общей памяти. Это доступно в каждой системе Unix, и также Windows имеет свой способ сделать его
Для использования общей памяти в Java, единственный путь состоит в том, чтобы реализовать его посредством собственного.DLL/.SO и JNI для доступа к нему.
Если Вы довольны записью JNI, рассматриваете Повышение. Межпроцессный. Это даст Вам портативную общую память и на Linux и на Windows. Помните, что нет никакого распространения в прямом и обратном направлениях ядра для чтения/записи общей памяти.
Я использовал бы локальный сокет с отрицательным подтверждением UDP, если бы скорость передачи будет слишком высокой для TCP (хотя я попробовал бы TCP сначала и подтвердил бы, что это - проблема). Там должно быть минимальным, если таковые имеются, пакеты, отброшенные, если Вы делаете потоковую передачу на той же машине, но добавление отрицательного слоя подтверждения будет заботиться о том случае для Вас.
Как насчет того, чтобы использовать System.out и System.in?
Если это не подходит, то Сокеты являются Вашим лучшим выбором.
Если Ваш процесс C++ запускает процесс Java, он мог бы извлечь выгоду из inheritedChannel. Кроме того, если процесс Java использует файл, я рекомендую исследование transferTo и transferFrom методов. Чтобы выполнение файла зарегистрировало IO, они стараются не напрасно смещаться назад и вперед между пространством ядра и пользователем; та же оптимизация могла бы умереть при использовании специального канала сокета.
Я рекомендую UDP "соединение", которое подтверждает каждый Энный пакет, который был получен без отказа и запрашивает повторную передачу нескольких пакетов, которые это пропустит.
Я отговорил бы от JNI, потому что очень трудно отладить. Если код C++ segfaults или выдаст неперехваченное исключение, то Ваша JVM откажет, и Вы будете понятия не иметь почему.
Самым быстрым решением будет отображение памяти в разделяемом сегменте памяти и реализация кольцевого буфера или другого механизма передачи сообщений. В C ++ это просто, а в Java у вас есть метод FileChannel.ma p, который делает это возможным.
Следующей альтернативой будет использование stdin / stdout двух процессов. Если один может выполнить другой, это может быть довольно быстро.
Наконец, как вы заметили, вы можете выполнять ввод-вывод сокета. Для потокового видео это не лучший вариант, но если вы передаете XML, накладные расходы будут минимальными по сравнению с другой обработкой.
Если это большой кусок данных в «одном» вызове функции, я бы порекомендовал JNI.
Взгляните на это: Совместное использование выходных потоков через интерфейс jni
Фрагмент из статьи, он передает данные из c ++ в java, обратное тоже будет легко сделать:
В целом, общая стратегия обмена двоичными данными (аудио / видео файлы, изображения и т. д.) из C с Java требует массивов байтов. Вы создаете массив байтов Java в C следующим образом:
const char[] rawData = {0,1,2,3,4,5,6,7,8,9}; //Or get some raw data from somewhere
int dataSize = sizeof(rawData);
printf("Building raw data array copy\n");
jbyteArray rawDataCopy = env->NewByteArray(dataSize);
env->SetByteArrayRegion(rawDataCopy, 0, dataSize, rawData);
И передаете его Java следующим образом:
printf("Finding callback method\n");
//Assumes obj is the Java instance that will receive the raw data via callback
jmethodID aMethodId = env->GetMethodID(env->GetObjectClass(obj),"handleData","([B)V");
if(0==aMethodId) throw MyRuntimeException("Method not found error");
printf("Invoking the callback\n");
env->CallVoidMethod(obj,aMethodId, &rawDataCopy);
у вас будет объект Java, который будет выглядеть примерно так:
public class MyDataHandler {
OutputStream dataStream;
public MyDataHandler(OutputStream writeTo) { dataStream = writeTo;}
public void handleData(byte[] incomingData) { dataStream.write(incomingData); }
}
Этот обработчик будет передан в C через собственный метод вот так:
public class NativeIntegration {
public native void generateBinaryWithHandler(MyDataHandler handler);
//Here we assume response is something like a network stream
public void doCallNativeFunction(ResponseStream response) {
MyDataHandler handler = new MyDataHandler(response);
generateBinaryWithHandler(handler);
}
}
Также вы можете использовать другие технологии: CORBA, ASN.1 ( инструмент ASN.1 ), UDP или TCP